#FaceCat-Ruby
#Shanghai JuanJuanMao Information Technology Co., Ltd 
require 'rexml/document'
include REXML
require 'fiddle'
require 'time'

$facecat = Fiddle.dlopen(Dir.pwd + "\\facecatcpp.dll")

WM_PAINT = 15
WM_SIZE = 5
WM_LBUTTONDOWN = 513
WM_MOUSEMOVE = 512
WM_LBUTTONUP = 514
WM_LBUTTONDBLCLK = 515
WM_RBUTTONDOWN = 516
WM_RBUTTONUP = 517
WM_RBUTTONDBLCLK = 518
WM_MOUSEWHEEL = 522
WM_IME_COMPOSITION = 271
WM_IME_CHAR = 646
WM_IME_SETCONTEXT = 641
WM_CHAR = 258
WM_KEYDOWN = 256
WM_KEYUP = 257
WM_SYSKEYDOWN = 260
WM_SYSKEYUP = 261

$beginWmPaint = Fiddle::Function.new(
  $facecat['beginWmPaint'],
  [Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$endWmPaint = Fiddle::Function.new(
  $facecat['endWmPaint'],
  [Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$createGdiPlus = Fiddle::Function.new(
  $facecat['createGdiPlus'],
  [Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$beginPaintGdiPlus2 = Fiddle::Function.new(
  $facecat['beginPaintGdiPlus2'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$endPaintGdiPlus = Fiddle::Function.new(
  $facecat['endPaintGdiPlus'],
  [Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$setOffsetGdiPlus = Fiddle::Function.new(
  $facecat['setOffsetGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$drawTextWithPosGdiPlus2 = Fiddle::Function.new(
  $facecat['drawTextWithPosGdiPlus2'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT64_T, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$getTextSizeWidth = Fiddle::Function.new(
  $facecat['getTextSizeWidth'],
  [],
  Fiddle::TYPE_INT
)
$getTextSizeHeight = Fiddle::Function.new(
  $facecat['getTextSizeHeight'],
  [],
  Fiddle::TYPE_INT
)
$textSizeGdiPlus4 = Fiddle::Function.new(
  $facecat['textSizeGdiPlus4'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$getWindowWidth = Fiddle::Function.new(
  $facecat['getWindowWidth'],
  [Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$getWindowHeight = Fiddle::Function.new(
  $facecat['getWindowHeight'],
  [Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$drawLineGdiPlus = Fiddle::Function.new(
  $facecat['drawLineGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$drawRectGdiPlus = Fiddle::Function.new(
  $facecat['drawRectGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$fillRectGdiPlus = Fiddle::Function.new(
  $facecat['fillRectGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$drawRoundRectGdiPlus = Fiddle::Function.new(
  $facecat['drawRoundRectGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$fillRoundRectGdiPlus = Fiddle::Function.new(
  $facecat['fillRoundRectGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$drawImageGdiPlus = Fiddle::Function.new(
  $facecat['drawImageGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOID, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$drawEllipseGdiPlus = Fiddle::Function.new(
  $facecat['drawEllipseGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$fillEllipseGdiPlus = Fiddle::Function.new(
  $facecat['fillEllipseGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$drawPolylineGdiPlus = Fiddle::Function.new(
  $facecat['drawPolylineGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP], 
  Fiddle::TYPE_INT
)
$drawPolygonGdiPlus = Fiddle::Function.new(
  $facecat['drawPolygonGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP], 
  Fiddle::TYPE_INT
)
$fillPolygonGdiPlus = Fiddle::Function.new(
  $facecat['fillPolygonGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT64_T, Fiddle::TYPE_VOIDP], 
  Fiddle::TYPE_INT
)
$setClipGdiPlus = Fiddle::Function.new(
  $facecat['setClipGdiPlus'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], 
  Fiddle::TYPE_INT
)
$showWindowMax = Fiddle::Function.new(
  $facecat['showWindowMax'],
  [],
  Fiddle::TYPE_INT
)
$getMouseX = Fiddle::Function.new(
  $facecat['getMouseX'],
  [Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$getMouseY = Fiddle::Function.new(
  $facecat['getMouseY'],
  [Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$setMessageState = Fiddle::Function.new(
  $facecat['setMessageState'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$createView = Fiddle::Function.new(
  $facecat['createView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_INT
)
$setAttribute2 = Fiddle::Function.new(
  $facecat['setAttribute2'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_INT
)
$paintView = Fiddle::Function.new(
  $facecat['paintView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$focusView = Fiddle::Function.new(
  $facecat['focusView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_INT
)
$unFocusView = Fiddle::Function.new(
  $facecat['unFocusView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_INT
)
$mouseDownView = Fiddle::Function.new(
  $facecat['mouseDownView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$mouseUpView = Fiddle::Function.new(
  $facecat['mouseUpView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$mouseMoveView = Fiddle::Function.new(
  $facecat['mouseMoveView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$mouseWheelView = Fiddle::Function.new(
  $facecat['mouseWheelView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT],
  Fiddle::TYPE_INT
)
$getHWnd = Fiddle::Function.new(
  $facecat['getHWnd'],
  [],
  Fiddle::TYPE_INT
)
$getMessage = Fiddle::Function.new(
  $facecat['getMessage'],
  [],
  Fiddle::TYPE_INT
)
$doMessage = Fiddle::Function.new(
  $facecat['doMessage'],
  [],
  Fiddle::TYPE_INT
)
$registerWndProc = Fiddle::Function.new(
  $facecat['registerWndProc'],
  [Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_VOID
)
$showWindow = Fiddle::Function.new(
  $facecat['showWindow'],
  [],
  Fiddle::TYPE_INT
)
$setCursor = Fiddle::Function.new(
  $facecat['setCursor'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_INT
)
$removeView = Fiddle::Function.new(
  $facecat['removeView'],
  [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP],
  Fiddle::TYPE_INT
)
$pumpMessage = Fiddle::Function.new(
  $facecat['pumpMessage'],
  [],
  Fiddle::TYPE_INT
)
#坐标结构
class FCPoint  
	attr_accessor :x, :y  
    
	def initialize(x, y)  
		@x = x  
		@y = y  
	end  
end

#大小结构
class FCSize  
	attr_accessor :cx, :cy  
    
	def initialize(cx, cy)  
		@cx = cx  
		@cy = cy  
	end  
end

#矩形结构
class FCRect  
	attr_accessor :left, :top, :right, :bottom  
    
	def initialize(left, top, right, bottom)  
		@left = left  
		@top = top  
		@right = right  
		@bottom = bottom  
	end  
end

#边距信息
class FCPadding  
	attr_accessor :left, :top, :right, :bottom  
    
	def initialize(left, top, right, bottom)  
		@left = left  
		@top = top  
		@right = right  
		@bottom = bottom  
	end  
end

#基础视图
class FCView  
	attr_accessor :align, :allowDrag, :allowResize, :allowDraw, :allowDragScroll, :allowPreviewsEvent, :autoHide, :backColor, :backImage, :borderColor, :borderWidth, :cornerRadius, :clipRect, :cursor, :dock, :downScrollHButton, :downScrollVButton, :displayOffset, :enabled, :exAttributes, :exView, :font, :hoverScrollHButton, :hoverScrollVButton, :hoveredColor, :hScrollIsVisible, :location, :margin, :maximumSize, :padding, :paint, :parent, :pushedColor, :resizePoint, :scrollV, :scrollH, :scrollSize, :showHScrollBar, :showVScrollBar, :scrollBarColor, :scrollBarHoveredColor, :size, :startPoint, :startScrollH, :startScrollV, :startRect, :tabIndex, :tabStop, :text, :textColor, :topMost, :touchDownTime, :verticalAlign, :viewName, :visible, :views, :viewType, :vScrollIsVisible
    
	def initialize()  
		@align = "left" #横向布局
		@allowDrag = false #是否允许拖动
		@allowResize = false #是否可以拖动改变大小
		@allowDraw = true #是否允许绘图
		@allowDragScroll = false #是否允许拖动滚动
		@allowPreviewsEvent = false #是否允许预处理事件
		@autoHide = false #是否自动隐藏
		@backColor = "rgb(255,255,255)" #背景色
		@backImage = "" #背景图片
		@borderColor = "rgb(150,150,150)" #边线色
		@borderWidth = 1 #边线宽度
		@cornerRadius = 0 #圆角
		@cursor = "" #光标
		@clipRect = nil #裁剪区域
		@dock = "none" #悬浮状态
		@downScrollHButton = false #是否按下横向滚动条
		@downScrollVButton = false #是否按下纵向滚动条
		@displayOffset = true #是否显示偏移量
		@enabled = true #是否可用
		@exAttributes = {} #额外属性
		@exView = false #是否扩展视图
		@font = "Default,14" #字体
		@hoverScrollHButton = false #是否悬停横向滚动条
		@hoverScrollVButton = false #是否悬停纵向滚动条
		@hoveredColor = "none" #鼠标悬停时的颜色
		@hScrollIsVisible = false #横向滚动是否显示
		@hWnd = nil #子视图句柄
		@location = FCPoint.new(0,0) #坐标
		@margin = FCPadding.new(0,0,0,0) #外边距
		@maximumSize = FCSize.new(0,0) #最大大小
		@padding = FCPadding.new(0,0,0,0) #内边距
		@paint = nil #绘图对象
		@parent = nil #父视图
		@pushedColor = "rgb(200,200,200)" #鼠标按下时的颜色
		@resizePoint = -1 #调整尺寸的点
		@scrollV = 0 #纵向滚动
		@scrollH = 0 #横向滚动
		@scrollSize = 8 #滚动条的大小
		@showHScrollBar = false #是否显示横向滚动条
		@showVScrollBar = false #是否显示横向滚动条
		@scrollBarColor = "rgb(200,200,200)" #滚动条的颜色
		@scrollBarHoveredColor = "rgb(42,138,195)" #滚动条悬停的颜色
		@size = FCSize.new(100,20) #大小
		@startPoint = nil #起始点
		@startScrollH = 0 #开始滚动的值
		@startScrollV = 0 #结束滚动的值
		@startRect = FCRect.new(0, 0, 0, 0) #移动开始时的视图矩形
		@tabIndex = 0 #Tab索引
		@tabStop = false #是否支持Tab
		@text = "" #文字
		@textColor = "rgb(0,0,0)" #前景色
		@topMost = false #是否置顶
		@touchDownTime = 0 #鼠标按下的时间
		@verticalAlign = "top" #纵向布局
		@viewName = "" #名称
		@visible = true #可见性
		@views = [] #子视图
		@viewType = "" #类型
		@vScrollIsVisible = false #纵向滚动是否显示
	end  
end

#按钮
class FCButton < FCView
	def initialize()  
		super()
		@viewType = "button" #类型
	end  
end

#标签
class FCLabel < FCView
	def initialize()  
		super()
		@backColor = "none" #背景色
		@viewType = "label" #类型
	end  
end

#文本框
class FCTextBox < FCView
	def initialize()  
		super()
		@viewType = "textbox" #类型
	end  
end

#图层
class FCDiv < FCView
def initialize()  
	super()
	@viewType = "div" #类型
end  
end

#复选按钮
class FCCheckBox < FCView
	attr_accessor :buttonSize, :checked

	def initialize()  
		super()
		@buttonSize = FCSize.new(16,16) #按钮的大小
		@checked = false #是否选中
		@viewType = "checkbox" #类型
	end  
end

#单选按钮
class FCRadioButton < FCView
	attr_accessor :buttonSize, :checked, :groupName

	def initialize()  
		super()
		@buttonSize = FCSize.new(16,16) #按钮的大小
		@checked = false #是否选中
		@groupName = "" #组别
		@viewType = "radiobutton" #类型
	end  
end

#页
class FCTabPage < FCView
	attr_accessor :headerButton

	def initialize()  
		super()
		@headerButton = nil #页头的按钮
		@viewType = "tabpage" #类型
		@visible = false #是否可见
	end  
end

#多页夹
class FCTabView < FCView
	attr_accessor :animationSpeed, :layout, :selectedIndex, :tabPages, :underLineColor, :underLineSize, :underPoint, :useAnimation

	def initialize()  
		super()
		@animationSpeed = 20 #动画速度
		@layout = "top" #布局方式
		@selectedIndex = -1 #选中索引
		@tabPages = [] #子页
		@underLineColor = "none" #下划线的颜色
		@underLineSize = 0 #下划线的宽度
		@underPoint = nil #下划点
		@useAnimation = false #是否使用动画
		@viewType = "tabview" #类型
	end  
end

#横竖布局图层
class FCLayoutDiv < FCView
	attr_accessor :autoWrap, :layoutStyle

	def initialize()  
		super()
		@autoWrap = false #是否自动换行
		@layoutStyle = "lefttoright" #分割方式
		@viewType = "layout" #类型
	end  
end

#横竖布局层
class FCLayoutDiv < FCView
	attr_accessor :autoWrap, :layoutStyle

	def initialize()  
		super()
		@autoWrap = false #是否自动换行
		@layoutStyle = "lefttoright" #分割方式
		@viewType = "layout" #类型
	end  
end

#分割布局层
class FCSplitLayoutDiv < FCView
	attr_accessor :firstView, :layoutStyle, :oldSize, :secondView, :splitMode, :splitPercent, :splitter

	def initialize()  
		super()
		@firstView = nil #第一个视图
		@layoutStyle = "lefttoright" #分割方式
		@oldSize = FCSize.new(0,0) #上次的尺寸
		@secondView = nil #第二个视图
		@splitMode = "absolutesize" #分割模式 percentsize百分比 或absolutesize绝对值
		@splitPercent = -1 #分割百分比
		@splitter = nil #分割线 
		@viewType = "split" #类型
	end  
end

#表格列
class FCGridColumn
	attr_accessor :allowSort, :allowResize, :backColor, :borderColor, :bounds, :cellAlign, :colName, :colType, :font, :frozen, :index, :sort, :text, :textColor, :visible, :width, :widthStr

	def initialize()  
		@allowSort = true #是否允许排序
		@allowResize = false #是否允许改变大小
		@backColor = "rgb(200,200,200)" #背景色
		@borderColor = "rgb(150,150,150)" #边线颜色
		@bounds = FCRect.new(0,0,0,0) #区域
		@cellAlign = "left" #left:居左 center:居中 right:居右
		@colName = "" #名称
		@colType = "" #类型 string:字符串 double:浮点型 int:整型 bool:布尔型
		@font = "Default,14" #字体
		@frozen = false #是否冻结
		@index = -1 #索引
		@sort = "none" #排序模式
		@text = "" #文字
		@textColor = "rgb(50,50,50)" #文字颜色
		@visible = true #是否可见
		@width = 120 #宽度
		@widthStr = "" #宽度字符串
	end  
end

#单元格
class FCGridCell
	attr_accessor :backColor, :borderColor, :colSpan, :column, :digit, :font, :rowSpan, :textColor, :value, :view

	def initialize()  
		@backColor = "none" #背景色
		@borderColor = "none" #边线颜色
		@colSpan = 1 #列距
		@column = nil #所在列
		@digit = -1 #保留小数的位数
		@font = "Default,14" #字体
		@rowSpan = 1 #行距
		@textColor = "rgb(0,0,0)" #文字颜色
		@value = nil #值
		@view = nil #包含的视图
	end  
end

#行
class FCGridRow
	attr_accessor :cells, :index, :key, :selected, :visible

	def initialize()  
		@cells =  [] #单元格
		@index = -1 #索引
		@key = "" #排序键值
		@selected = false #是否选中
		@visible = true #是否可见
	end  
end

#表格
class FCGrid < FCView
	attr_accessor :columns, :headerHeight, :rowHeight, :rows, :seletedRowColor, :showHScrollBar, :showVScrollBar

	def initialize()  
		super()
		@columns = [] #列
		@headerHeight = 30 #头部高度
		@rowHeight = 30 #行高
		@rows = [] #行
		@seletedRowColor = "rgb(125,125,125)" #选中行的颜色
		@showHScrollBar = true #是否显示横向滚动条
		@showVScrollBar = true #是否显示横向滚动条
		@viewType = "grid" #类型
	end  
end

#树的列
class FCTreeColumn
	attr_accessor :bounds, :index, :visible, :width, :widthStr

	def initialize()  
		@bounds = FCRect.new(0,0,0,0) #区域
		@index = -1 #索引
		@visible = true #是否可见
		@width = 120 #宽度
		@widthStr = "" #宽度字符串
	end  
end

#树的行
class FCTreeRow
	attr_accessor :cells, :index, :selected, :visible

	def initialize()  
		@cells = [] #单元格
		@index = -1 #索引
		@selected = false #是否选中
		@visible = true #是否可见
	end  
end

#树节点
class FCTreeNode
	attr_accessor :allowCollapsed, :backColor, :checked, :childNodes, :collapsed, :column, :font, :indent, :parentNode, :row, :value, :textColor

	def initialize()  
		@allowCollapsed = true #是否允许折叠
		@backColor = "none" #背景色
		@checked = false #是否选中
		@childNodes = [] #子节点
		@collapsed = false #是否折叠
		@column = nil #所在列
		@font = "Default,14" #字体
		@indent = 0 #缩进
		@parentNode = nil #父节点
		@row = nil #所在行
		@value = nil #值
		@textColor = "rgb(0,0,0)" #文字颜色	
	end  
end

#树节点
class FCTree < FCView
	attr_accessor :checkBoxWidth, :childNodes, :collapsedWidth, :columns, :headerHeight, :indent, :rowHeight, :rows, :showCheckBox, :showHScrollBar, :showVScrollBar

	def initialize() 
		super()
		@checkBoxWidth = 25 #复选框占用的宽度
		@childNodes = [] #子节点
		@collapsedWidth = 25 #折叠按钮占用的宽度
		@columns = [] #列
		@headerHeight = 0 #头部高度
		@indent = 20 #缩进
		@rowHeight = 30 #行高
		@rows = [] #行
		@showCheckBox = false #是否显示复选框
		@showHScrollBar = true #是否显示横向滚动条
		@showVScrollBar = true #是否显示横向滚动条
		@viewType = "tree" #类型
	end  
end

#证券数据结构
class SecurityData
	attr_accessor :amount, :close, :date, :high, :low, :open, :volume

	def initialize()  
		@amount = 0 #成交额
		@close = 0 #收盘价
		@date = 0 #日期，为1970年到现在的秒
		@high = 0 #最高价
		@low = 0 #最低价
		@open = 0 #开盘价
		@volume = 0 #成交额
	end  
end

#基础图形
class BaseShape
	attr_accessor :color, :color2, :datas, :datas2, :divIndex, :leftOrRight, :lineWidth, :shapeName, :shapeType, :showHideDatas, :style, :text, :title, :title2, :value

	def initialize()  
		@color = "none" #颜色
		@color2 = "none" #颜色2
		@datas = [] #第一组数据
		@datas2 = [] #第二组数据
		@divIndex = 0 #所在层
		@leftOrRight = true #依附于左轴或右轴
		@lineWidth = 1 #线的宽度
		@shapeName = "" #名称
		@shapeType = "line" #类型
		@showHideDatas = [] #控制显示隐藏的数据
		@style = "" #样式
		@text = "" #显示的文字
		@title = "" #第一个标题
		@title2 = "" #第二个标题
		@value = 0 #显示文字的值
	end  
end

#画线工具结构
class FCPlot
	attr_accessor :key1, :key2, :key3, :plotType, :pointColor, :lineColor, :lineWidth, :lineWidth, :startKey1, :startValue1, :startKey2, :startValue2, :startKey3, :startValue3, :value1, :value2, :value3

	def initialize()  
		@key1 = nil #第一个键
		@key2 = nil #第二个键
		@key3 = nil #第三个键
		@plotType = "Line" #线的类型
		@pointColor = "rgba(0,0,0,125)" #线的颜色
		@lineColor = "rgb(0,0,0)" #线的颜色
		@lineWidth = 1 #线的宽度
		@startKey1 = nil #移动前第一个键
		@startValue1 = nil #移动前第一个值
		@startKey2 = nil #移动前第二个键
		@startValue2 = nil #移动前第二个值
		@startKey3 = nil #移动前第三个键
		@startValue3 = nil #移动前第三个值
		@value1 = nil #第一个值
		@value2 = nil #第二个值
		@value3 = nil #第三个值
	end  
end

#图表
class FCChart < FCView
	attr_accessor :addingPlot, :allowDragScroll, :autoFillHScale, :allowDragChartDiv, :candleDistance, :candleMax, :candleMin, :candleMaxRight, :candleMinRight, :crossTipColor, :crossLineColor, :candleDivPercent, :candleDigit, :candlePaddingTop, :candlePaddingBottom, :crossStopIndex, :cycle, :data, :downColor, :firstVisibleIndex, :gridColor, :hScalePixel, :hScaleHeight, :hScaleFormat, :hScaleTextDistance, :indMax, :indMin, :indMax2, :indMin2, :indMaxRight, :indMinRight, :indMax2Right, :indMin2Right, :indDigit, :indDigit2, :indDivPercent, :indDivPercent2, :indPaddingTop, :indPaddingBottom, :indPaddingTop2, :indPaddingBottom2, :indicatorColors, :leftVScaleWidth, :lastVisibleIndex, :lastRecordIsVisible, :lastVisibleKey, :lastValidIndex, :lineWidthChart, :mainIndicator, :magnitude, :nMaxHigh, :nMaxLow, :plots, :plotPointSizeChart, :rightVScaleWidth, :rightSpace, :shapes, :scaleColor, :showIndicator, :showCrossLine, :selectPlotPoint, :sPlot, :startMovePlot, :selectShape, :selectShapeEx, :touchPosition, :touchDownPointChart, :volMax, :volMin, :volMaxRight, :volMinRight, :volDigit, :volDivPercent, :volPaddingTop, :volPaddingBottom, :vScaleDistance, :vScaleType, :upColor, :closearr, :allema12, :allema26, :alldifarr, :alldeaarr, :allmacdarr, :boll_up, :boll_down, :boll_mid, :bias1, :bias2, :bias3, :kdj_k, :kdj_d, :kdj_j, :rsi1, :rsi2, :rsi3, :roc, :roc_ma, :wr1, :wr2, :cci, :bbi, :trix, :trix_ma, :dma1, :dma2, :ma5, :ma10, :ma20, :ma30, :ma120, :ma250, :gridStep, :gridDigit, :firstIndexCache, :firstTouchIndexCache, :firstTouchPointCache, :lastIndexCache, :secondTouchIndexCache, :secondTouchPointCache, :firstPaddingTop, :firstPaddingBottom, :kChart, :bChart, :oXChart, :oYChart, :rChart, :x4Chart, :y4Chart, :nHighChart, :nLowChart, :xChart, :yChart, :wChart, :hChart, :upSubValue, :downSubValue

	def initialize()  
		super()
		@addingPlot = "" #要添加的画线
		@allowDragScroll = true #是否允许拖动滚动
		@autoFillHScale = false #是否填充满X轴
		@allowDragChartDiv = false #是否允许拖拽图层
		@candleDistance = 0 #蜡烛线的距离
		@candleMax = 0 #蜡烛线的最大值
		@candleMin = 0 #蜡烛线的最小值
		@candleMaxRight = 0 #蜡烛线的右轴最大值
		@candleMinRight = 0 #蜡烛线的右轴最小值
		@crossTipColor = "rgb(50,50,50)" #十字线标识的颜色
		@crossLineColor = "rgb(100,100,100)" #十字线的颜色
		@candleDivPercent = 0.5 #图表层的占比
		@candleDigit = 2 #图表层保留小数的位数
		@candlePaddingTop = 30 #图表层的上边距
		@candlePaddingBottom = 30 #图表层的下边距
		@crossStopIndex = -1 #鼠标停留位置
		@cycle = "second" #周期
		@data = [] #图表数据
		@downColor = "rgb(15,193,118)" #下跌颜色
		@firstVisibleIndex = -1 #起始可见的索引
		@font = "Default,14" #字体
		@gridColor = "rgb(50,0,0)" #网格颜色 
		@hScalePixel = 11 #蜡烛线的宽度
		@hScaleHeight = 30 #X轴的高度
		@hScaleFormat = "" #X轴的格式化字符，例如%Y-%m-%d %H:%M:%S
		@hScaleTextDistance = 10 #X轴的文字间隔
		@indMax = 0 #指标层的最大值
		@indMin = 0 #指标层的最小值
		@indMax2 = 0 #指标层2的最大值
		@indMin2 = 0 #指标层2的最小值
		@indMaxRight = 0 #指标层的右轴最大值
		@indMinRight = 0 #指标层的右轴最小值
		@indMax2Right = 0 #指标层2的右轴最大值
		@indMin2Right = 0 #指标层2的右轴最小值
		@indDigit = 2 #指标层保留小数的位数
		@indDigit2 = 2 #指标层2保留小数的位数
		@indDivPercent = 0.3 #指标层的占比
		@indDivPercent2 = 0.0 #指标层2的占比
		@indPaddingTop = 20 #指标层的上边距
		@indPaddingBottom = 20 #指标层的下边距
		@indPaddingTop2 = 20 #指标层2的上边距
		@indPaddingBottom2 = 20 #指标层2的下边距
		@indicatorColors = [] #指标的颜色
		@leftVScaleWidth = 0 #左轴宽度
		@lastVisibleIndex = -1 #结束可见的索引
		@lastRecordIsVisible = true #最后记录是否可见
		@lastVisibleKey = 0 #最后可见的主键
		@lastValidIndex = -1 #最后有效数据索引
		@lineWidthChart = 1
		@mainIndicator = "" #主图指标
		@magnitude = 1 #成交量的比例
		@plots = [] #画线的集合
		@plotPointSizeChart = 5 #画线的选中点大小
		@rightVScaleWidth = 100 #右轴宽度
		@rightSpace = 0 #右侧空间
		@shapes = [] #扩展图形
		@scaleColor = "rgb(100,0,0)" #刻度的颜色
		@showIndicator = "" #显示指标
		@showCrossLine = false #是否显示十字线
		@selectPlotPoint = -1 #选中画线的点
		@sPlot = nil #选中的画线
		@startMovePlot = false #选中画线
		@selectShape = "" #选中的图形
		@selectShapeEx = "" #选中的图形信息
		@touchPosition = FCPoint.new(0,0) #鼠标坐标
		@touchDownPointChart = FCPoint.new(0, 0)
		@volMax = 0 #成交量层的最大值
		@volMin = 0 #成交量层的最小值
		@volMaxRight = 0 #成交量层的右轴最大值
		@volMinRight = 0 #成交量层的右轴最小值
		@volDigit = 0 #成交量层保留小数的位数
		@volDivPercent = 0.2 #成交量层的占比
		@volPaddingTop = 20 #成交量层的上边距
		@volPaddingBottom = 0 #成交量层的下边距
		@vScaleDistance = 35 #纵轴的间隔
		@vScaleType = "standard" #纵轴的类型 log10代表指数坐标
		@viewType = "chart" #类型
		@upColor = "rgb(219,68,83)" #上涨颜色
		@closearr = []
		@allema12 = []
		@allema26 = []
		@alldifarr = []
		@alldeaarr = []
		@allmacdarr = []
		@boll_up = []
		@boll_down = []
		@boll_mid = []
		@bias1 = []
		@bias2 = []
		@bias3 = []
		@kdj_k = []
		@kdj_d = []
		@kdj_j = []
		@rsi1 = []
		@rsi2 = []
		@rsi3 = []
		@roc = []
		@roc_ma = []
		@wr1 = []
		@wr2 = []
		@cci = []
		@bbi = []
		@trix = []
		@trix_ma = []
		@dma1 = []
		@dma2 = []
		@ma5 = []
		@ma10 = []
		@ma20 = []
		@ma30 = []
		@ma120 = []
		@ma250 = []
		@gridStep = 0 #网格计算临时变量
		@gridDigit = 0 #网格计算临时变量
		@firstIndexCache = -1
		@firstTouchIndexCache = -1
		@firstTouchPointCache = FCPoint.new(0,0)
		@lastIndexCache = -1
		@secondTouchIndexCache = -1
		@secondTouchPointCache = FCPoint.new(0,0)
		@firstPaddingTop = 0
		@firstPaddingBottom = 0
		@kChart = 0
		@bChart = 0
		@oXChart = 0
		@oYChart = 0
		@rChart = 0
		@x4Chart = 0
		@y4Chart = 0
		@nHighChart = 0
		@nLowChart = 0
		@xChart = 0
		@yChart = 0
		@wChart = 0
		@hChart = 0
		@upSubValue = 0
		@downSubValue = 0
		@nMaxHigh = 0
		@nMaxLow = 0

	end  
end

#日期按钮
class DayButton
	attr_accessor :backColor, :borderColor, :bounds, :calendar, :day, :font, :inThisMonth, :selected, :textColor, :textColor2, :visible

	def initialize()  
		@backColor = "none" #背景颜色
		@borderColor = "rgb(150,150,150)" #文字颜色 
		@bounds = FCRect.new(0,0,0,0) #显示区域
		@calendar =  nil #日历视图
		@day = nil #日
		@font = "Default,16" #字体
		@inThisMonth = false #是否在本月
		@selected = false #是否被选中
		@textColor = "rgb(0,0,0)" #文字颜色
		@textColor2 = "rgb(50,50,50)" #第二个文字颜色
		@visible = true #是否可见
	end  
end

#月的按钮
class MonthButton
	attr_accessor :backColor, :borderColor, :bounds, :calendar, :font, :month, :textColor, :visible, :year

	def initialize()  
		@backColor = "none" #背景颜色
		@borderColor = "rgb(150,150,150)" #文字颜色 
		@bounds = FCRect.new(0,0,0,0) #显示区域
		@calendar = nil #日历视图
		@font = "Default,16" #字体
		@month = 0 #月
		@textColor = "rgb(0,0,0)" #文字颜色
		@visible = true #是否可见
		@year = 0 #年
	end  
end

#年的按钮
class YearButton
	attr_accessor :backColor, :borderColor, :bounds, :calendar, :font, :textColor, :visible, :year

	def initialize()  
		@backColor = "none" #背景颜色
		@borderColor = "rgb(150,150,150)" #文字颜色 
		@bounds = FCRect.new(0,0,0,0) #显示区域
		@calendar = nil #日历视图
		@font = "Default,16" #字体
		@textColor = "rgb(0,0,0)" #文字颜色
		@visible = true #是否可见
		@year = 0 #年
	end  
end

#日期层
class DayDiv
	attr_accessor :aClickRowFrom, :aClickRowTo, :aDirection, :aTick, :aTotalTick, :calendar, :dayButtons, :dayButtons_am

	def initialize()  
		@aClickRowFrom = 0 #点击时的上月的行
		@aClickRowTo = 0 #点击时的当月的行
		@aDirection = 0 #动画的方向
		@aTick = 0 #动画当前帧数
		@aTotalTick = 40 #动画总帧数
		@calendar = nil #日历视图
		@dayButtons = [] #日期的集合
		@dayButtons_am = []  #动画日期的集合
	end  
end

#月层
class MonthDiv
	attr_accessor :aDirection, :aTick, :aTotalTick, :calendar, :month, :monthButtons, :monthButtons_am, :year

	def initialize()  
		@aDirection = 0 #动画的方向
		@aTick = 0 #动画当前帧数
		@aTotalTick = 40 #动画总帧数
		@calendar = nil #日历视图
		@month = 0 #月份
		@monthButtons = [] #月的按钮
		@monthButtons_am = [] #月的动画按钮
		@year = 0 #年份
	end  
end

#年层
class YearDiv
	attr_accessor :aDirection, :aTick, :aTotalTick, :calendar, :startYear, :yearButtons, :yearButtons_am

	def initialize()  
		@aDirection = 0 #动画的方向
		@aTick = 0 #动画当前帧数
		@aTotalTick = 40 #动画总帧数
		@calendar = nil #日历视图
		@startYear = 0 #开始年份
		@yearButtons = [] #月的按钮
		@yearButtons_am = [] #月的动画按钮
	end  
end

#头部层
class HeadDiv
	attr_accessor :arrowColor, :backColor, :calendar, :bounds, :textColor, :titleFont, :weekFont

	def initialize()  
		@arrowColor = "rgb(150,150,150)" #箭头颜色
		@backColor = "rgb(255,255,255)" #箭头颜色
		@calendar = nil #日历视图
		@bounds = FCRect.new(0,0,0,0) #显示区域
		@textColor = "rgb(0,0,0)" #文字颜色
		@titleFont = "Default,20" #标题字体
		@weekFont = "Default,14" #星期字体
	end  
end

#时间层
class TimeDiv
	attr_accessor :bounds, :calendar

	def initialize()  
		@bounds = FCRect.new(0,0,0,0) #显示区域
		@calendar = nil #日历视图
	end  
end

#年的结构
class CYear
	attr_accessor :months, :year

	def initialize()  
		@months = {} #月的集合
		@year = 0 #年
	end  
end

#月的结构
class CMonth
	attr_accessor :days, :month, :year

	def initialize()  
		@days = {} #日的集合
		@month = 0 #月
		@year = 0 #年
	end  
end

#日的结构
class CDay
	attr_accessor :day, :month, :year

	def initialize()  
		@day = 0 #日
		@month = 0 #月
		@year = 0 #年
	end  
end

#日历
class FCCalendar < FCView
	attr_accessor :dayDiv, :headDiv, :mode, :monthDiv, :selectedDay, :timeDiv, :useAnimation, :yearDiv, :years

	def initialize()  
		super()
		@dayDiv = DayDiv.new() #日层
		@headDiv = HeadDiv.new() #头部层
		@mode = "day" #模式
		@monthDiv = MonthDiv.new() #月层
		@selectedDay = nil #选中日
		@timeDiv = TimeDiv.new() #时间层
		@useAnimation = false #是否使用动画
		@viewType = "calendar" #类型
		@yearDiv = YearDiv.new() #年层
		@years = {} #日历
	end  
end

#菜单
class FCMenu < FCLayoutDiv
	attr_accessor :autoSize, :autoWrap, :comboBox, :items, :layoutStyle, :popup

	def initialize()  
		super()
		@autoSize = true #是否自动适应尺寸
		@autoWrap = false
		@comboBox = nil #所在的下拉菜单
		@items = [] #菜单项
		@layoutStyle = "toptobottom"
		@maximumSize = FCSize.new(100,300) #最大大小
		@popup = true #是否弹出
		@showHScrollBar = true
		@showVScrollBar = true 
		@size = FCSize.new(100, 100)
		@viewType = "menu"
		@visible = false
	end  
end

#菜单
class FCMenuItem < FCView
	attr_accessor :checked, :dropDownMenu, :items, :parentMenu, :parentItem, :value

	def initialize()  
		super()
		@checked = false #是否选中
		@dropDownMenu = nil #下拉菜单
		@hoveredColor = "rgb(150,150,150)"
		@items = [] #菜单项
		@parentMenu = nil #所在菜单
		@parentItem = nil #父菜单项
		@pushedColor = "rgb(200,200,200)"
		@size = FCSize.new(100, 25)
		@value = "" #值
		@viewType = "menuitem"
	end  
end

#菜单
class FCComboBox < FCView
	attr_accessor :dropDownMenu, :selectedIndex

	def initialize()  
		super()
		@dropDownMenu = nil #下拉菜单 
		@selectedIndex = -1 #选中索引
		@viewType = "combobox"
	end  
end

#转换颜色
#strColor:颜色字符
def toColorGdiPlus(strColor)
	strColor = strColor.gsub("(", "")
	strColor = strColor.gsub(")", "")
	if strColor.include?("rgba")
		strColor = strColor.gsub("rgba", "")
		strs = strColor.split(",")
		if strs.length >= 4
			r = strs[0].to_i
			g = strs[1].to_i
			b = strs[2].to_i
			a = strs[3].to_i
			rgb = ((r | (g << 8)) | (b << 0x10))
			if a == 255
				return rgb
			elsif a == 0
				return -2000000000
			else
				return -(rgb * 1000 + a)
			end
		end
	elsif strColor.include?("rgb")
		strColor = strColor.gsub("rgb", "")
		strs = strColor.split(",")
		if strs.length >= 3
			r = strs[0].to_i
			g = strs[1].to_i
			b = strs[2].to_i
			rgb = ((r | (g << 8)) | (b << 0x10))
			return rgb
		end
	elsif strColor != "none" && strColor.length > 0
		return strColor.to_f.to_i
	end
	return 0
end

#绘图对象
class FCPaint
	attr_accessor :cancelClick, :clipRect, :context, :defaultUIStyle, :dragBeginPoint, :dragBeginRect, :draggingView, :focusedView, :fontSize, :gID, :hWnd, :isClip, :isDoubleClick, :isPath, :offsetX, :offsetY, :moveTo, :resizeColumnState, :resizeColumnBeginWidth, :resizeColumnIndex, :scaleFactorX, :scaleFactorY, :size, :systemFont, :touchDownView, :touchMoveView, :touchDownPoint, :views, :onCalculateChartMaxMin, :onClick, :onContainsPoint, :onClickGridCell, :onClickGridColumn, :onClickTreeNode, :onInvalidate, :onInvalidateView, :onKeyDown, :onKeyUp, :onChar, :onPaint, :onPaintBorder, :onPaintCalendarDayButton, :onPaintCalendarMonthButton, :onPaintCalendarYearButton, :onPaintChartScale, :onPaintChartHScale, :onPaintChartStock, :onPaintChartPlot, :onPaintChartCrossLine, :onPaintGridCell, :onPaintGridColumn, :onPaintHeadDiv, :onPaintTreeNode, :onMouseDown, :onMouseMove, :onMouseUp, :onMouseWheel, :onMouseEnter, :onMouseLeave, :onRenderViews, :onUpdateView, :textSizeCache
	def initialize()  
		@cancelClick = false #是否退出点击
		@clipRect = nil #裁剪区域
		@context = nil #上下文
		@defaultUIStyle = "light" #默认样式
		@dragBeginPoint = FCPoint.new(0, 0) #拖动开始时的触摸位置
		@dragBeginRect = FCRect.new(0, 0, 0, 0) #拖动开始时的区域
		@draggingView = nil #正被拖动的控件
		@focusedView = nil #焦点视图
		@fontSize = 19 #当前的字体大小
		@gID = -1 #唯一编号
		@hWnd = 0 #句柄
		@isClip = false #是否裁剪
		@isDoubleClick = nil #是否双击
		@isPath = nil #是否路径
		@offsetX = 0 #横向偏移
		@offsetY = 0 #纵向偏移
		@moveTo = nil
		@resizeColumnState = 0 #改变列宽度的状态
		@resizeColumnBeginWidth = 0 #改变列宽度的起始值
		@resizeColumnIndex = -1 #改变列宽度的索引
		@scaleFactorX = 1 #横向缩放比例
		@scaleFactorY = 1 #纵向缩放比例
		@size = FCSize.new(0,0) #布局大小
		@systemFont = "Segoe UI" #系统字体
		@touchDownView = nil #鼠标按下的视图
		@touchMoveView = nil #鼠标移动的视图
		@touchDownPoint = FCPoint.new(0,0)
		@views = [] #子视图 
		@onCalculateChartMaxMin = nil #计算最大最小值的回调
		@onClick = nil #点击的回调
		@onClickGridCell = nil #点击单元格的事件回调
		@onClickGridColumn = nil #点击列头的事件回调
		@onClickTreeNode = nil #点击树节点的事件回调
		@onContainsPoint = nil #包含点的回调
		@onInvalidate = nil
		@onInvalidateView = nil
		@onKeyDown = nil #键盘按下的回调
		@onKeyUp = nil #键盘抬起的回调
		@onChar = nil #键盘输入的回调
		@onPaint = nil #绘图回调
		@onPaintBorder = nil #绘制边线的回调
		@onPaintCalendarDayButton = nil
		@onPaintCalendarMonthButton = nil
		@onPaintCalendarYearButton = nil
		@onPaintChartScale = nil #绘制坐标轴回调
		@onPaintChartHScale = nil #绘制坐标轴回调
		@onPaintChartStock = nil #绘制图表回调
		@onPaintChartPlot = nil #绘制画线回调
		@onPaintChartCrossLine = nil #绘制十字线回调
		@onPaintGridCell = nil #绘制单元格的事件回调
		@onPaintGridColumn = nil #绘制列头的事件回调
		@onPaintHeadDiv = nil
		@onPaintTreeNode = nil #绘图树节点的事件回调
		@onMouseDown = nil #鼠标按下的回调
		@onMouseMove = nil #鼠标移动的回调
		@onMouseUp = nil #鼠标抬起的回调
		@onMouseWheel = nil #鼠标滚动的回调
		@onMouseEnter = nil #鼠标进入的回调
		@onMouseLeave = nil #鼠标离开的回调
		@onRenderViews = nil
		@onUpdateView = nil #更新布局的回调
		@textSizeCache = {}
	end

	#开始绘图 
	#rect:区域
	def beginPaint(rect, pRect)
		$beginPaintGdiPlus2.call(@gID.to_i, rect.left.to_i, rect.top.to_i, rect.right.to_i, rect.bottom.to_i, pRect.left.to_i, pRect.top.to_i, pRect.right.to_i, pRect.bottom.to_i)
	end
	#绘制线
	#color:颜色 
	#width:宽度 
	#style:样式 
	#x1:横坐标1 
	#y1:纵坐标1 
	#x2:横坐标2 
	#y2:纵坐标2
	def drawLine(color, width, style, x1, y1, x2, y2)
		inStyle = style.to_i
		$drawLineGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), width.to_i, inStyle, x1.to_i, y1.to_i, x2.to_i, y2.to_i)
	end
	#绘制连续线
	#color:颜色 
	#width:宽度 
	#style:样式 
	#apt:坐标集合
	def drawPolyline(color, width, style, apt)
		strApt = ""
		for i in 0..apt.length - 1
			x = apt[i].x
			y = apt[i].y
			strApt += x.to_s + "," + y.to_s
			if i != apt.length - 1
				strApt += " "
			end
		end
		inStyle = style.to_i
		pPoints = Fiddle::Pointer[strApt]
		$drawPolylineGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), width.to_i, inStyle, pPoints)
	end
	#绘制多边形
	#color:颜色 
	#width:宽度 
	#style:样式 
	#apt:坐标集合
	def drawPolygon(color, width, style, apt)
		strApt = ""
		for i in 0..apt.length - 1
			x = apt[i].x
			y = apt[i].y
			strApt += x.to_s + "," + y.to_s
			if i != apt.length - 1
				strApt += " "
			end
		end
		inStyle = style.to_i
		pPoints = Fiddle::Pointer[strApt]
		$drawPolygonGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), width.to_i, inStyle, pPoints)
	end
	#绘制矩形 
	#color:颜色 
	#width:宽度 
	#style:样式 
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:下方坐标
	def drawRect(color, width, style, left, top, right, bottom)
		inStyle = style.to_i
		$drawRectGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), width.to_i, inStyle, left.to_i, top.to_i, right.to_i, bottom.to_i)
	end
	#绘制圆角矩形 
	#color:颜色 
	#width:宽度 
	#style:样式 
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:下方坐标
	#cornerRadius:圆角
	def drawRoundRect(color, width, style, left, top, right, bottom, cornerRadius)
		inStyle = style.to_i
		if cornerRadius > 0
			$drawRoundRectGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), width.to_i, inStyle, left.to_i, top.to_i, right.to_i, bottom.to_i, cornerRadius.to_i)
		else
			$drawRectGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), width.to_i, inStyle, left.to_i, top.to_i, right.to_i, bottom.to_i)
		end
	end
	#绘制图片 
	#image:图片路径
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:下方坐标
	def drawImage(image, left, top, right, bottom)
		pImage = Fiddle::Pointer[image]
		$drawImageGdiPlus.call(@gID.to_i, pImage, left.to_i, top.to_i, right.to_i, bottom.to_i)
	end
	#绘制椭圆 
	#color:颜色 
	#width:宽度 
	#style:样式 
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:下方坐标
	def drawEllipse(color, width, style, left, top, right, bottom)
		inStyle = style.to_i
		$drawEllipseGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), width.to_i, inStyle, left.to_i, top.to_i, right.to_i, bottom.to_i)
	end

	#绘制文字大小 
	#text:文字 
	#color:颜色 
	#font:字体 
	#x:横坐标 
	#y:纵坐标
	def drawText(text, color, font, x, y)
		font = font.gsub("Default", @systemFont)
		pText = Fiddle::Pointer[text]
		pFont = Fiddle::Pointer[font]
		$drawTextWithPosGdiPlus2.call(@gID.to_i, pText, toColorGdiPlus(color).to_i(), pFont, x.to_i, y.to_i)
	end
	#结束绘图
	def endPaint()
		$endPaintGdiPlus.call(@gID.to_i)
	end
	#填充矩形 
	#color:颜色
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:下方坐标
	def fillRect(color, left, top, right, bottom)
		$fillRectGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), left.to_i, top.to_i, right.to_i, bottom.to_i)
	end
	#填充矩形 
	#color:颜色
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:下方坐标
	#cornerRadius:圆角
	def fillRoundRect(color, left, top, right, bottom, cornerRadius)
		if cornerRadius > 0
			$fillRoundRectGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), left.to_i, top.to_i, right.to_i, bottom.to_i, cornerRadius.to_i)
		else
			$fillRectGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), left.to_i, top.to_i, right.to_i, bottom.to_i)
		end
	end
	#填充多边形 
	#color:颜色
	#apt:坐标集合
	def fillPolygon(color, apt)
		strApt = ""
		for i in 0..apt.length - 1
			x = apt[i].x
			y = apt[i].y
			strApt += x.to_s + "," + y.to_s
			if i != apt.length - 1
				strApt += " "
			end
		end
		pPoints = Fiddle::Pointer[strApt]
		$fillPolygonGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), pPoints)
	end
	#填充椭圆 
	#color:颜色
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:下方坐标
	def fillEllipse(color, left, top, right, bottom)
		$fillEllipseGdiPlus.call(@gID.to_i, toColorGdiPlus(color).to_i(), left.to_i, top.to_i, right.to_i, bottom.to_i)
	end
	#设置偏移量
	#offsetX:横向偏移 
	#offsetY:纵向偏移
	def setOffset(offsetX, offsetY)
		$setOffsetGdiPlus.call(@gID.to_i, offsetX.to_i, offsetY.to_i)
	end
	#获取字体大小 
	#text:文字 
	#font:字体
	def textSize(text, font)
		font = font.gsub("Default", @systemFont)
		key = text + font
		if textSizeCache.has_key?(key)
			return textSizeCache[key]
		else
			pText = Fiddle::Pointer[text]
			pFont = Fiddle::Pointer[font]
			$textSizeGdiPlus4.call(@gID.to_i, pText, pFont, -1)
			width = $getTextSizeWidth.call()
			height = $getTextSizeHeight.call()
			tSize = FCSize.new(width, height)
			textSizeCache[key] = tSize
			return tSize
		end
	end
	#绘制矩形 
	#text文字 
	#color:颜色 
	#font:字体 
	#left:左侧坐标 
	#top:上方坐标 
	#right:右侧坐标 
	#bottom:方坐标
	def drawTextAutoEllipsis(text, color, font, left, top, right, bottom)
		tSize = textSize(text, font)
		if tSize.cx < right - left
			drawText(text, color, font, left, top)
		else
			if tSize.cx > 0
				subLen = 3
				while 1 == 1
					newLen = text.length - subLen
					if newLen > 0
						newText = text[0,newLen] + "..."
						tSize = textSize(newText, font)
						if tSize.cx < right - left
							drawText(newText, color, font, left, top)
							break
						else
							subLen += 3
						end
					else
						break
					end
				end
			end
		end
	end
	#设置裁剪
	#rect:区域
	def setClip(left, top, right, bottom)
		$setClipGdiPlus.call(@gID.to_i, left.to_i, top.to_i, right.to_i, bottom.to_i)
	end
end

#添加顶层视图
#view 视图
#paint 绘图对象
def addView(view, paint)
	view.paint = paint
	paint.views.push(view)
end

#添加到父视图
#view 视图
#parent 父视图
def addViewToParent(view, parent)
	view.parent = parent
	view.paint = parent.paint
	parent.views.push(view)
end

#隐藏视图
#mp 坐标
#paint 绘图对象
def autoHideView(mp, paint)
	hideView = false
	for i in 0..paint.views.length - 1
		view = paint.views[i]
		if view.autoHide
			size = view.size
			location = view.location
			if mp.x < location.x || mp.x > location.x + size.cx || mp.y < location.y || mp.y > location.y + size.cy
				if view.visible
					view.visible = false
					hideView = true
				end
			end
		end
	end
	if hideView
		invalidate(paint)
	end
end

#清除输入框
#views:视图集合
def clearViewInputs(views)
	for i in 0..views.length - 1
		view = views[i]
		if view.exView
			pName = Fiddle::Pointer[view.viewName]
			$removeView.call(view.paint.gID.to_i, pName)
		end
	end
end

#清除视图
def clearViews(paint)
	clearViewInputs(paint.views)
	paint.views = []
end

#移除顶层视图
#view 视图
#paint 绘图对象
def removeView(view, paint)
	for i in 0..paint.views.length - 1
		if paint.views[i] == view
			paint.views.delete_at(i)
			if view.exView
				removeViews = []
				removeViews.append(view)
				clearViewInputs(removeViews)
			end
			break
		end
	end
end

#从父视图中移除
#view 视图
#parent 父视图
def removeViewFromParent(view, parent)
	for i in 0..parent.views.length - 1
		if parent.views[i] == view
			parent.views.delete_at(i)
			if view.exView
				removeViews = []
				removeViews.append(view)
				clearViewInputs(removeViews)
			end
			break
		end
	end
end

#获取绝对位置X 
#view:视图
def clientX(view)
	if view != nil
		cLeft = view.location.x
		if view.parent != nil
			if view.parent.displayOffset
				return cLeft + clientX(view.parent) - view.parent.scrollH
			else
				return cLeft + clientX(view.parent)
			end
		else
			return cLeft
		end
	else
		return 0
	end
end

#获取绝对位置Y 
#view:视图
def clientY(view)
	if view != nil
		cTop = view.location.y
		if view.parent != nil
			if view.parent.displayOffset
				return cTop + clientY(view.parent) - view.parent.scrollV
			else
				return cTop + clientY(view.parent)
			end
		else
			return cTop
		end
	else
		return 0
	end
end

#是否重绘时可见 
#view:视图
def isPaintVisible(view)
	if view.visible
        if view.parent != nil
            if view.parent.visible
                return isPaintVisible(view.parent)
            else
                return false
			end
        else
            return true
		end
    else
        return false
	end
end

#是否可用 
#view:视图
def isViewEnabled(view)
	if view.enabled
		if view.parent != nil
			if view.parent.enabled
				return isViewEnabled(view.parent)
			else
				return false
			end
		else
			return true
		end
	else
		return false
	end
end

#是否包含坐标 
#view:视图 
#mp:坐标
def containsPoint(view, mp)
	if isViewEnabled(view)
		clx = clientX(view)
		cly = clientY(view)
		size = view.size
		cp = FCPoint.new(0,0)
		cp.x = mp.x - clx
		cp.y = mp.y - cly
		if cp.x >= 0 && cp.x <= size.cx && cp.y >= 0 && cp.y <= size.cy
			return true
		else
			return false
		end
	else
		return false
	end
end

#根据名称查找视图 
#name:名称
#views:视图集合
def findViewByName(name, views)
	size = views.length
	if size > 0
		for i in 0..size - 1
			view = views[i]
			if view.viewName == name
				return view
			else
				subViews = view.views
				if subViews.length > 0
					subView = findViewByName(name, subViews)
					if subView != nil
						return subView
					end
				end
			end
		end
	end
	return nil
end

#获取区域的交集
def getIntersectRect(lpDestRect, lpSrc1Rect, lpSrc2Rect)
	lpDestRect.left = [lpSrc1Rect.left, lpSrc2Rect.left].max
	lpDestRect.right = [lpSrc1Rect.right, lpSrc2Rect.right].min
	lpDestRect.top = [lpSrc1Rect.top, lpSrc2Rect.top].max
	lpDestRect.bottom = [lpSrc1Rect.bottom, lpSrc2Rect.bottom].min
	if lpDestRect.right > lpDestRect.left && lpDestRect.bottom > lpDestRect.top
		return 1
	else
		lpDestRect.left = 0
		lpDestRect.right = 0
		lpDestRect.top = 0
		lpDestRect.bottom = 0
		return 0
	end
end

#根据坐标查找视图 
#mp:坐标 
#views:视图集合
def findView(mp, views)
	size = views.length
	if size > 0
		#先判断置顶视图
		for i in 0..size
			view = views[size - i - 1]
			if view.visible && view.topMost
				hasPoint = false
				paint = view.paint
				if paint != nil && paint.onContainsPoint != nil
					hasPoint = paint.onContainsPoint.call(view, mp)
				else
					hasPoint = containsPoint(view, mp)
				end
				if hasPoint
					if view.vScrollIsVisible && view.scrollSize > 0
						clx = clientX(view)
						if mp.x >= clx + view.size.cx - view.scrollSize
							return view
						end
					end
					if view.hScrollIsVisible && view.scrollSize > 0
						cly = clientY(view)
						if mp.y >= cly + view.size.cy - view.scrollSize
							return view
						end
					end
					subViews = view.views
					if subViews.length > 0
						subView = findView(mp, subViews)
						if subView != nil
							return subView
						end
					end
					return view
				end
			end
		end
		#再判断非置顶视图
		for i in 0..size
			view = views[size - i - 1]
			if view.visible && view.topMost == false
				hasPoint = false
				paint = view.paint
				if paint != nil && paint.onContainsPoint != nil
					hasPoint = paint.onContainsPoint.call(view, mp)
				else
					hasPoint = containsPoint(view, mp)
				end
				if hasPoint
					if view.vScrollIsVisible && view.scrollSize > 0
						clx = clientX(view)
						if mp.x >= clx + view.size.cx - view.scrollSize
							return view
						end
					end
					if view.hScrollIsVisible && view.scrollSize > 0
						cly = clientY(view)
						if mp.y >= cly + view.size.cy - view.scrollSize
							return view
						end
					end
					subViews = view.views
					if subViews.length > 0
						subView = findView(mp, subViews)
						if subView != nil
							return subView
						end
					end
					return view
				end
			end
		end
	end
	return nil
end

#重绘复选按钮 
#checkBox:视图 
#paint:绘图对象 
#clipRect:裁剪区域
def drawCheckBox(checkBox, paint, clipRect)
	width = checkBox.size.cx
	height = checkBox.size.cy
	if checkBox.textColor != "none"
		eRight = checkBox.buttonSize.cx + 10
		eRect = FCRect.new(1, (height - checkBox.buttonSize.cy) / 2, checkBox.buttonSize.cx + 1, (height + checkBox.buttonSize.cy) / 2)
		if checkBox.text.length == 0
			eRect = FCRect.new((width - checkBox.buttonSize.cx) / 2, (height - checkBox.buttonSize.cy) / 2, (width + checkBox.buttonSize.cx) / 2, (height + checkBox.buttonSize.cy) / 2)
		end
		paint.drawRect(checkBox.textColor, 1, 0, eRect.left, eRect.top, eRect.right, eRect.bottom)
		#绘制选中区域
		if checkBox.checked
			eRect.left += 2
			eRect.top += 2
			eRect.right -= 2
			eRect.bottom -= 2
			drawPoints = []
			drawPoints.push(FCPoint.new(eRect.left, eRect.top + 8))
			drawPoints.push(FCPoint.new(eRect.left + 6, eRect.bottom))
			drawPoints.push(FCPoint.new(eRect.right - 1, eRect.top))
			paint.drawPolyline(checkBox.textColor, 1, 0, drawPoints)
		end
		if checkBox.text.length > 0
			tSize = paint.textSize(checkBox.text, checkBox.font)
			paint.drawText(checkBox.text, checkBox.textColor, checkBox.font, eRight, (height - tSize.cy) / 2)	
		end
	end
end		

#重绘单选按钮 
#checkBox:视图 
#paint:绘图对象 
#clipRect:裁剪区域
def drawRadioButton(radioButton, paint, clipRect)
	width = radioButton.size.cx
	height = radioButton.size.cy
	if radioButton.textColor != "none"
		eRight = radioButton.buttonSize.cx + 10
		eRect = FCRect.new(1, (height - radioButton.buttonSize.cy) / 2, radioButton.buttonSize.cx + 1, (height + radioButton.buttonSize.cy) / 2)
		paint.drawEllipse(radioButton.textColor, 1, 0, eRect.left, eRect.top, eRect.right, eRect.bottom)
		#绘制选中区域
		if radioButton.checked
			eRect.left += 2
			eRect.top += 2
			eRect.right -= 3
			eRect.bottom -= 3
			paint.fillEllipse(radioButton.textColor, eRect.left, eRect.top, eRect.right, eRect.bottom)
		end
		tSize = paint.textSize(radioButton.text, radioButton.font)
		paint.drawText(radioButton.text, radioButton.textColor, radioButton.font, eRight, (height - tSize.cy) / 2)	
	end
end	

#点击复选按钮 
#checkBox:视图
#mp: 坐标
def clickCheckBox(checkBox, mp)
	if checkBox.checked
		checkBox.checked = false
	else
		checkBox.checked = true
	end
end

#点击单选按钮 
#radioButton:视图
#mp: 坐标
def clickRadioButton(radioButton, mp)
	hasOther = false
	if(radioButton.parent != nil && radioButton.parent.views.length > 0)
		#将相同groupName的单选按钮都取消选中
		for i in 0..radioButton.parent.views.length - 1
			rView = radioButton.parent.views[i]
			if rView.viewType == "radiobutton"
				if rView != radioButton && rView.groupName == radioButton.groupName
					rView.checked = false
				end
			end
		end
	end
	radioButton.checked = true
end

#重绘按钮 
#button:视图 
#paint:绘图对象 
#clipRect:裁剪区域
def drawButton(button, paint, clipRect)
	#鼠标按下
	if button == paint.touchDownView
		if button.pushedColor != "none"
			paint.fillRoundRect(button.pushedColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius)
		else
			if button.backColor != "none"
				paint.fillRoundRect(button.backColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius)
			end
		end
	#鼠标悬停
	elsif button == paint.touchMoveView
		if button.hoveredColor != "none"
			paint.fillRoundRect(button.hoveredColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius)
		else
			if button.backColor != "none"
				paint.fillRoundRect(button.backColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius)
			end
		end
	#常规情况
	elsif button.backColor != "none"
		paint.fillRoundRect(button.backColor, 0, 0, button.size.cx, button.size.cy, button.cornerRadius)
	end
	#绘制文字
	if button.textColor != "none" && button.text.length > 0
		tSize = paint.textSize(button.text, button.font)
		paint.drawText(button.text, button.textColor, button.font, (button.size.cx - tSize.cx) / 2, (button.size.cy  - tSize.cy) / 2)
	end
	#绘制边线
	if button.borderColor != "none"
		paint.drawRoundRect(button.borderColor, button.borderWidth, 0, 0, 0, button.size.cx, button.size.cy, button.cornerRadius)
	end
end

#获取内容的宽度 
#div:图层
def getDivContentWidth(div)
	cWidth = 0
	subViews = div.views
	for i in 0..subViews.length - 1
		view = subViews[i]
		if view.visible
			if cWidth < view.location.x + view.size.cx
				cWidth = view.location.x + view.size.cx
			end
		end
	end
	return cWidth
end

#获取内容的高度 
#div:图层
def getDivContentHeight(div)
	cHeight = 0
	subViews = div.views
	for i in 0..subViews.length - 1
		view = subViews[i]
		if view.visible
			if cHeight < view.location.y + view.size.cy
				cHeight = view.location.y + view.size.cy
			end
		end
	end
	return cHeight
end

#绘制滚动条 
#div:图层 
#paint:绘图对象 
#clipRect:裁剪区域
def drawDivScrollBar(div, paint, clipRect)
	div.hScrollIsVisible = false
	div.vScrollIsVisible = false
	#判断横向滚动条
	if div.showHScrollBar
		contentWidth = getDivContentWidth(div)
		if contentWidth > 0 && contentWidth > div.size.cx
			sLeft = div.size.cx * div.scrollH / contentWidth
			sRight = div.size.cx * (div.scrollH + div.size.cx) / contentWidth
			if sRight - sLeft < div.scrollSize
				sRight = sLeft + div.scrollSize
			end
			if paint.touchMoveView == div && (div.hoverScrollHButton || div.downScrollHButton)
				paint.fillRect(div.scrollBarHoveredColor, sLeft, div.size.cy - div.scrollSize, sRight, div.size.cy)
			else
				paint.fillRect(div.scrollBarColor, sLeft, div.size.cy - div.scrollSize, sRight, div.size.cy)
			end
			div.hScrollIsVisible = true
		end
	end
	#判断纵向滚动条
	if div.showVScrollBar
		contentHeight = getDivContentHeight(div)	
		if contentHeight > 0 && contentHeight > div.size.cy
			sTop = div.scrollV * div.size.cy / contentHeight
			sBottom = sTop + (div.size.cy * div.size.cy / contentHeight)
			if sBottom - sTop < div.scrollSize
				sBottom = sTop + div.scrollSize
			end
			if paint.touchMoveView == div && (div.hoverScrollVButton || div.downScrollVButton)
				paint.fillRect(div.scrollBarHoveredColor, div.size.cx - div.scrollSize, sTop, div.size.cx, sBottom)
			else
				paint.fillRect(div.scrollBarColor, div.size.cx - div.scrollSize, sTop, div.size.cx, sBottom)
			end
			div.vScrollIsVisible = true
		end
	end
end

#重绘图层边线 
#div:视图 
#paint:绘图对象 
#clipRect:裁剪区域
def drawDivBorder(div, paint, clipRect)
	if div.borderColor != "none"
		paint.drawRoundRect(div.borderColor, div.borderWidth, 0, 0, 0, div.size.cx, div.size.cy, div.cornerRadius)
	end
end

#重绘图形 
#div:视图 
#paint:绘图对象 
#clipRect:裁剪区域
def drawDiv(div, paint, clipRect)
	if div.backColor != "none"
		paint.fillRoundRect(div.backColor, 0, 0, div.size.cx, div.size.cy, div.cornerRadius)
	end
end

#图层的鼠标滚轮方法 
#div:图层 
#delta:滚轮值
def touchWheelDiv(div, delta)
	oldScrollV = div.scrollV
	if delta > 0
		oldScrollV -= 10
	elsif delta < 0
		oldScrollV += 10
	end
	contentHeight = getDivContentHeight(div)
	if contentHeight < div.size.cy
		div.scrollV = 0
	else
		if oldScrollV < 0
			oldScrollV = 0
		elsif oldScrollV > contentHeight - div.size.cy
			oldScrollV = contentHeight - div.size.cy
		end
		div.scrollV = oldScrollV
	end
end

#图层的鼠标抬起方法 
#div: 图层 
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks 点击次数
def touchUpDiv(div, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	div.downScrollHButton = false
	div.downScrollVButton = false
	div.hoverScrollHButton = false
	div.hoverScrollVButton = false
end


#图层的鼠标按下方法 
#div: 图层 
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks 点击次数
def touchDownDiv(div, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	mp = firstPoint
	div.startPoint = mp
	div.downScrollHButton = false
	div.downScrollVButton = false
	div.hoverScrollHButton = false
	div.hoverScrollVButton = false
	#判断横向滚动条
	if div.showHScrollBar
		contentWidth = getDivContentWidth(div)
		if contentWidth > 0 && contentWidth > div.size.cx
			sLeft = div.size.cx * div.scrollH / contentWidth
			sRight = div.size.cx * (div.scrollH + div.size.cx) / contentWidth
			if sRight - sLeft < div.scrollSize
				sRight = sLeft + div.scrollSize
			end
			if mp.x >= sLeft && mp.x <= sRight && mp.y >= div.size.cy - div.scrollSize && mp.y <= div.size.cy
				div.downScrollHButton = true
				div.startScrollH = div.scrollH
				return
			end
		end
	end
	#判断纵向滚动条
	if div.showVScrollBar
		contentHeight = getDivContentHeight(div)
		if contentHeight > 0 && contentHeight > div.size.cy
			sTop = div.size.cy * div.scrollV / contentHeight
			sBottom = div.size.cy * (div.scrollV + div.size.cy) / contentHeight
			if sBottom - sTop < div.scrollSize
				sBottom = sTop + div.scrollSize
			end
			if mp.x >= div.size.cx - div.scrollSize && mp.x <= div.size.cx && mp.y >= sTop && mp.y <= sBottom
				div.downScrollVButton = true
				div.startScrollV = div.scrollV
				return
			end
		end
	end
	if div.allowDragScroll
		div.startScrollH = div.scrollH
		div.startScrollV = div.scrollV
	end
end

#图层的鼠标移动方法 
#div: 图层 
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
def touchMoveDiv(div, firstTouch, firstPoint, secondTouch, secondPoint)
	div.hoverScrollHButton = false
	div.hoverScrollVButton = false
	mp = firstPoint
	if firstTouch
		if div.showHScrollBar || div.showVScrollBar
			#判断横向滚动条
			if div.downScrollHButton
				contentWidth = getDivContentWidth(div)
				subX = contentWidth * (mp.x - div.startPoint.x) / div.size.cx
				newScrollH = div.startScrollH + subX
				if newScrollH < 0
					newScrollH = 0
				elsif newScrollH > contentWidth - div.size.cx
					newScrollH = contentWidth - div.size.cx
				end
				div.scrollH = newScrollH
				div.paint.cancelClick = true
				return
			#判断纵向滚动条
			elsif div.downScrollVButton
				contentHeight = getDivContentHeight(div)
				subY = contentHeight * (mp.y - div.startPoint.y) / div.size.cy
				newScrollV = div.startScrollV + subY
				if newScrollV < 0
					newScrollV = 0
				elsif newScrollV > contentHeight - div.size.cy
					newScrollV = contentHeight - div.size.cy
				end
				div.scrollV = newScrollV
				div.paint.cancelClick = true
				return
			end
		end
		#判断拖动
		if div.allowDragScroll
			contentWidth = getDivContentWidth(div)
			if contentWidth > div.size.cx
				subX = div.startPoint.x - mp.x
				newScrollH = div.startScrollH + subX
				if newScrollH < 0
					newScrollH = 0
				elsif newScrollH > contentWidth - div.size.cx
					newScrollH = contentWidth - div.size.cx
				end
				div.scrollH = newScrollH
				if subX.abs > 5
					div.paint.cancelClick = true
				end
			end
			contentHeight = getDivContentHeight(div)
			if contentHeight > div.size.cy
				subY = div.startPoint.y - mp.y
				newScrollV = div.startScrollV + subY
				if newScrollV < 0
					newScrollV = 0
				elsif newScrollV > contentHeight - div.size.cy
					newScrollV = contentHeight - div.size.cy
				end
				div.scrollV = newScrollV
				if subY.abs > 5
					div.paint.cancelClick = true
				end
			end
		end
	else
		#判断横向滚动条
		if div.showHScrollBar
			contentWidth = getDivContentWidth(div)
			if contentWidth > 0 && contentWidth > div.size.cx
				sLeft = div.size.cx * div.scrollH / contentWidth
				sRight = div.size.cx * (div.scrollH + div.size.cx) / contentWidth
				if sRight - sLeft < div.scrollSize
					sRight = sLeft + div.scrollSize
				end
				if mp.x >= sLeft && mp.x <= sRight && mp.y >= div.size.cy - div.scrollSize && mp.y <= div.size.cy
					div.hoverScrollHButton = true
					return
				else
					div.hoverScrollHButton = false
				end
			end
		end
		#判断纵向滚动条
		if div.showVScrollBar
			contentHeight = getDivContentHeight(div)
			if contentHeight > 0 && contentHeight > div.size.cy
				sTop = div.size.cy * div.scrollV / contentHeight
				sBottom = div.size.cy * (div.scrollV + div.size.cy) / contentHeight
				if sBottom - sTop < div.scrollSize
					sBottom = sTop + div.scrollSize
				end
				if mp.x >= div.size.cx - div.scrollSize && mp.x <= div.size.cx && mp.y >= sTop && mp.y <= sBottom
					div.hoverScrollVButton = true
					return
				else
					div.hoverScrollVButton = false
				end
			end
		end
	end
end

#重绘多页加 
#tabView:多页夹 
#paint:绘图对象 
#clipRect:裁剪区域
def drawTabViewBorder(tabView, paint, clipRect)
	if tabView.underLineColor != "none"
		tabPages = tabView.tabPages
		for i in 0..tabPages.length - 1
			tp = tabPages[i]
			if tp.visible
				headerButton = tp.headerButton
				location = FCPoint.new(headerButton.location.x, headerButton.location.y)
				size = headerButton.size
				if tabView.useAnimation
					if tabView.underPoint != nil
						location.x = tabView.underPoint.x
						location.y = tabView.underPoint.y
					end
				end
				if tabView.layout == "bottom"
					paint.fillRect(tabView.underLineColor, location.x, location.y, location.x + size.cx, location.y + tabView.underLineSize)
				elsif tabView.layout == "left"
					paint.fillRect(tabView.underLineColor, location.x + size.cx - tabView.underLineSize, location.y, location.x + size.cx, location.y + size.cy)
				elsif tabView.layout == "top"
					paint.fillRect(tabView.underLineColor, location.x, location.y + size.cy - tabView.underLineSize, location.x + size.cx, location.y + size.cy)
				elsif tabView.layout == "right"
					paint.fillRect(tabView.underLineColor, location.x, location.y, location.x + tabView.underLineSize, location.y + size.cy)
				end
				break
			end
		end
	end
end

#更新页的布局 
#tabView:多页夹 
#tabPage:页 
#left:左侧坐标 
#top:上方坐标 
#width:宽度 
#height:高度 
#tw:页头按钮的宽度 
#th:页头按钮的高度
def updataPageLayout(tabView, tabPage, left, top, width, height, tw, th)
	newBounds = FCRect.new(0, 0, 0, 0)
	#下方
	if tabView.layout == "bottom"
		newBounds.left = 0
		newBounds.top = 0
		newBounds.right = width
		newBounds.bottom = height - th
		tabPage.headerButton.location = FCPoint.new(left, height - th)
	#左侧
	elsif tabView.layout == "left"
		newBounds.left = tw
		newBounds.top = 0
		newBounds.right = width
		newBounds.bottom = height
		tabPage.headerButton.location = FCPoint.new(0, top)
	#右侧
	elsif tabView.layout == "right"
		newBounds.left = 0
		newBounds.top = 0
		newBounds.right = width - tw
		newBounds.bottom = height
		tabPage.headerButton.location = FCPoint.new(width - tw, top)
	#上方
	elsif tabView.layout == "top"
		newBounds.left = 0
		newBounds.top = th
		newBounds.right = width
		newBounds.bottom = height
		tabPage.headerButton.location = FCPoint.new(left, 0)
	end
	tabPage.location = FCPoint.new(newBounds.left, newBounds.top)
	tabPage.size = FCSize.new(newBounds.right - newBounds.left, newBounds.bottom - newBounds.top)
end

#更新多页夹的布局 
#tabView:多页夹
def updateTabLayout(tabView)
	width = tabView.size.cx
	height = tabView.size.cy
	left = 0
	top = 0
	tabPages = tabView.tabPages
	for i in 0..tabPages.length - 1
		tabPage = tabPages[i]
		headerButton = tabPage.headerButton
		if headerButton.visible
			tw = headerButton.size.cx
			th = headerButton.size.cy
			updataPageLayout(tabView, tabPage, left, top, width, height, tw, th)
			left += tw
			top += th
		else
			tabPage.visible = false
		end
	end
end

#添加页 
#tabView:多页夹 
#tabPage:页 
#tabButton:页头按钮
def addTabPage(tabView, tabPage, tabButton)
	tabPage.headerButton = tabButton
	tabPage.parent = tabView
	tabPage.paint = tabView.paint
	tabButton.parent = tabView
	tabButton.paint = tabView.paint
	tabView.tabPages.push(tabPage)
	tabView.views.push(tabPage)
	tabView.views.push(tabButton)
end

#选中页 
#tabView:多页夹 
#tabPage:页
def selectTabPage(tabView, tabPage)
	tabPages = tabView.tabPages
	for i in 0..tabPages.length - 1
		tp = tabPages[i]
		if tp == tabPage
			tp.visible = true
		else
			tp.visible = false
		end
	end
	updateTabLayout(tabView)
end

#重置布局图层 
#layout:布局层
def resetLayoutDiv(layout)
	reset = false
	padding = layout.padding
	vPos = 0
	left = padding.left
	top = padding.top
	width = layout.size.cx - padding.left - padding.right
	height = layout.size.cy - padding.top - padding.bottom
	i = 0
	subViews = layout.views
	for i in 0..subViews.length - 1
		view = subViews[i]
		if view.visible
			size = FCSize.new(view.size.cx, view.size.cy)
			margin = view.margin
			cLeft = view.location.x
			cTop = view.location.y
			cWidth = size.cx
			cHeight = size.cy
			nLeft = cLeft
			nTop = cTop
			nWidth = cWidth
			nHeight = cHeight
			#从下至上
			if layout.layoutStyle == "bottomtotop"
				if i == 0
					top = height - padding.top
				end
				lWidth = 0
				if layout.autoWrap
					lWidth = size.cx
					lTop = top - margin.top - cHeight - margin.bottom
					if lTop < padding.top
						if vPos != 0
							left += cWidth + margin.left
						end
						top = height - padding.top
					end
				else
					lWidth = width - margin.left - margin.right
				end
				top -= cHeight + margin.bottom
				nLeft = left + margin.left
				nWidth = lWidth
				nTop = top
			#从左到右
			elsif layout.layoutStyle == "lefttoright"
				lHeight = 0
				if layout.autoWrap
					lHeight = size.cy
					lRight = left + margin.left + cWidth + margin.right
					if lRight > width
						left = padding.left
						if vPos != 0
							top += cHeight + margin.top
						end
					end
				else
					lHeight = height - margin.top - margin.bottom
				end
				left += margin.left
				nLeft = left
				nTop = top + margin.top
				nHeight = lHeight
				left += cWidth + margin.right
			#从右到左
			elsif layout.layoutStyle == "righttoleft"
				if i == 0
					left = width - padding.left
				end
				lHeight = 0
				if layout.autoWrap
					lHeight = size.cy
					lLeft = left - margin.left - cWidth - margin.right
					if lLeft < padding.left
						left = width - padding.left
						if vPos != 0
							top += cHeight + margin.top
						end
					end
				else
					lHeight = height - margin.top - margin.bottom
				end
				left -= cWidth + margin.left
				nLeft = left
				nTop = top + margin.top
				nHeight = lHeight
			#从上至下
			elsif layout.layoutStyle == "toptobottom"
				lWidth = 0
				if layout.autoWrap
					lWidth = size.cx
					lBottom = top + margin.top + cHeight + margin.bottom
					if lBottom > height
						if vPos != 0
							left += cWidth + margin.left + margin.right
						end
						top = padding.top
					end
				else
					lWidth = width - margin.left - margin.right
					top += margin.top
					nTop = top
					nLeft = left + margin.left
					nWidth = lWidth
					top += cHeight + margin.bottom
				end
			end
			if cLeft != nLeft || cTop != nTop || cWidth != nWidth || cHeight != nHeight
				view.location = FCPoint.new(nLeft, nTop)
				view.size = FCSize.new(nWidth, nHeight)
				reset = true
			end
			vPos = vPos + 1
		end
	end
	return reset
end

#重置分割线的布局
#split:分割视图
def resetSplitLayoutDiv(split)
	reset = false
	splitRect = FCRect.new(0, 0, 0, 0)
	width = split.size.cx
	height = split.size.cy
	fRect = FCRect.new(0, 0, 0, 0)
	sRect = FCRect.new(0, 0, 0, 0)
	splitterSize = FCSize.new(0, 0)
	if split.splitter.visible
		splitterSize.cx = split.splitter.size.cx
		splitterSize.cy = split.splitter.size.cy
	end
	layoutStyle = split.layoutStyle 
	#从下至上
	if layoutStyle == "bottomtotop"
		if split.splitMode == "absolutesize" || split.oldSize.cy == 0
			splitRect.left = 0
			splitRect.top = height - (split.oldSize.cy - split.splitter.location.y)
			splitRect.right = width
			splitRect.bottom = splitRect.top + splitterSize.cy
		elsif split.splitMode == "percentsize"
			splitRect.left = 0
			if split.splitPercent == -1
				split.splitPercent = split.splitter.location.y / split.oldSize.cy
			end
			splitRect.top = height * split.splitPercent
			splitRect.right = width
			splitRect.bottom = splitRect.top + splitterSize.cy
		end
		fRect.left = 0
		fRect.top = splitRect.bottom
		fRect.right = width
		fRect.bottom = height
		sRect.left = 0
		sRect.top = 0
		sRect.right = width
		sRect.bottom = splitRect.top
	#从左至右
	elsif layoutStyle == "lefttoright"
		if split.splitMode == "absolutesize" || split.oldSize.cx == 0
			splitRect.left = split.splitter.location.x
			splitRect.top = 0
			splitRect.right = splitRect.left + splitterSize.cx
			splitRect.bottom = height
		elsif split.splitMode == "percentsize"
			if split.splitPercent == -1
				split.splitPercent = split.splitter.location.x / split.oldSize.cx
			end
			splitRect.left = width * split.splitPercent
			splitRect.top = 0
			splitRect.right = splitRect.left + splitterSize.cx
			splitRect.bottom = height
		end
		fRect.left = 0
		fRect.top = 0
		fRect.right = splitRect.left
		fRect.bottom = height
		sRect.left = splitRect.right
		sRect.top = 0
		sRect.right = width
		sRect.bottom = height
	#从右到左
	elsif layoutStyle == "righttoleft"
		if split.splitMode == "absolutesize" || split.oldSize.cx == 0
			splitRect.left = width - (split.oldSize.cx - split.splitter.location.x)
			splitRect.top = 0
			splitRect.right = splitRect.left + splitterSize.cx
			splitRect.bottom = height
		elsif split.splitMode == "percentsize"
			if split.splitPercent == -1
				split.splitPercent = split.splitter.location.x / split.oldSize.cx
			end
			splitRect.left = width * split.splitPercent
			splitRect.top = 0
			splitRect.right = splitRect.left + splitterSize.cx
			splitRect.bottom = height
		end
		fRect.left = splitRect.right
		fRect.top = 0
		fRect.right = width
		fRect.bottom = height
		sRect.left = 0
		sRect.top = 0
		sRect.right = splitRect.left
		sRect.bottom = height
	#从上至下
	elsif layoutStyle == "toptobottom"
		if split.splitMode == "absolutesize" || split.oldSize.cy == 0
			splitRect.left = 0
			splitRect.top = split.splitter.location.y
			splitRect.right = width
			splitRect.bottom = splitRect.top + splitterSize.cy
		elsif split.splitMode == "percentsize"
			splitRect.left = 0
			if split.splitPercent == -1
				split.splitPercent = split.splitter.location.y / split.oldSize.cy
			end
			splitRect.top = height * split.splitPercent
			splitRect.right = width
			splitRect.bottom = splitRect.top + splitterSize.cy
		end
		fRect.left = 0
		fRect.top = 0
		fRect.right = width
		fRect.bottom = splitRect.top
		sRect.left = 0
		sRect.top = splitRect.bottom
		sRect.right = width
		sRect.bottom = height
	end
	#重置分割条
	if split.splitter.visible
		spRect = FCRect.new(split.splitter.location.x,  split.splitter.location.y, split.splitter.location.x + split.splitter.size.cx, split.splitter.location.y + split.splitter.size.cy)
		if spRect.left != splitRect.left || spRect.top != splitRect.top || spRect.right != splitRect.right || spRect.bottom != splitRect.bottom
			split.splitter.location = FCPoint.new(splitRect.left, splitRect.top)
			split.splitter.size = FCSize.new(splitRect.right - splitRect.left, splitRect.bottom - splitRect.top)
			reset = true
		end
	end
	fcRect = FCRect.new(split.firstView.location.x,  split.firstView.location.y, split.firstView.location.x + split.firstView.size.cx, split.firstView.location.y + split.firstView.size.cy)
	#重置第一个视图
	if fcRect.left != fRect.left || fcRect.top != fRect.top || fcRect.right != fRect.right || fcRect.bottom != fRect.bottom
		reset = true
		split.firstView.location = FCPoint.new(fRect.left, fRect.top)
		split.firstView.size = FCSize.new(fRect.right - fRect.left, fRect.bottom - fRect.top)
	end
	scRect = FCRect.new(split.secondView.location.x,  split.secondView.location.y, split.secondView.location.x + split.secondView.size.cx, split.secondView.location.y + split.secondView.size.cy)
	#重置第二个视图
	if scRect.left != sRect.left || scRect.top != sRect.top || scRect.right != sRect.right || scRect.bottom != sRect.bottom
		reset = true
		split.secondView.location = FCPoint.new(sRect.left, sRect.top)
		split.secondView.size = FCSize.new(sRect.right - sRect.left, sRect.bottom - sRect.top)
	end
	split.oldSize = FCSize.new(width, height)
	return reset
end

#快速添加表格列
#grid:表格
#columns:列名集合
def fastAddGridColumns(grid, columns)
	columnsSize = columns.length
	for i in 0..columnsSize - 1
		gridColumn = FCGridColumn.new()
		gridColumn.text = columns[i]
		grid.columns.push(gridColumn)
	end
end

#快速添加表格行
#grid:表格
#datas:数据集合
def fastAddGridRow(grid, datas)
	gridRow = FCGridRow.new()
	datasSize = datas.length
	for i in 0..datasSize - 1
		gridCell = FCGridCell.new()
		gridCell.value = datas[i]
		gridRow.cells.push(gridCell)
	end
	return gridRow
end

#添加视图到单元格
#view:视图
#cell:单元格
#grid:表格
def addViewToGridCell(view, cell, grid)
	view.displayOffset = false
	view.visible = false
	cell.view = view
	addViewToParent(view, grid)
end

#表格的鼠标滚轮方法 
#grid:表格 
#delta:滚轮值
def touchWheelGrid(grid, delta)
	oldScrollV = grid.scrollV
	if delta > 0
		oldScrollV -= grid.rowHeight
	elsif delta < 0
		oldScrollV += grid.rowHeight
	end
	contentHeight = getGridContentHeight(grid)
	if contentHeight < grid.size.cy - grid.headerHeight - grid.scrollSize
		grid.scrollV = 0
	else
		if oldScrollV < 0
			oldScrollV = 0
		elsif oldScrollV > contentHeight - grid.size.cy + grid.headerHeight + grid.scrollSize
			oldScrollV = contentHeight - grid.size.cy + grid.headerHeight + grid.scrollSize
		end
		grid.scrollV = oldScrollV
	end
end

#绘制单元格 
#grid:表格 
#row:行 
#column:列 
#cell:单元格
#paint:绘图对象 
#left:左侧坐标 
#top:上方坐标 
#right:右侧坐标 
#bottom:下方坐标
def drawGridCell(grid, row, column, cell, paint, left, top, right, bottom)
	#绘制背景
	if cell.backColor != "none"
		paint.fillRect(cell.backColor, left, top, right, bottom)
	end
	#绘制选中
	if row.selected
		if(grid.seletedRowColor != "none")
			paint.fillRect(grid.seletedRowColor, left, top, right, bottom)
		end
	end
	#绘制边线
	if cell.borderColor != "none"
		#paint.drawRect(cell.borderColor, 1, 0, left, top, right, bottom)
		paint.drawLine(cell.borderColor, 1, 0, left, bottom, right, bottom)
		paint.drawLine(cell.borderColor, 1, 0, right - 1, top, right - 1, bottom)
	end
	#绘制数值
	if cell.value != nil
		showText = cell.value.to_s
		if column.colType == "double"
			if cell.digit >= 0
				numValue = showText.to_f
				showText = toFixed(numValue, cell.digit)
			end
		end
		tSize = paint.textSize(showText, cell.font)
		if tSize.cx > right - left
			paint.drawTextAutoEllipsis(showText, cell.textColor, cell.font, left + 2, top + grid.rowHeight / 2 - tSize.cy / 2, right - 2, top + grid.rowHeight / 2 + tSize.cy / 2)
		else
			if column.cellAlign == "left"
				paint.drawText(showText, cell.textColor, cell.font, left + 2, top + grid.rowHeight / 2 - tSize.cy / 2)
			elsif column.cellAlign == "center"
				paint.drawText(showText, cell.textColor, cell.font, left + (right - left - tSize.cx) / 2, top + grid.rowHeight / 2 - tSize.cy / 2)
			elsif column.cellAlign == "right"
				paint.drawText(showText, cell.textColor, cell.font, right - tSize.cx, top + grid.rowHeight / 2 - tSize.cy / 2)	
			end
		end
	end
end

#获取内容的宽度 
#grid:表格
def getGridContentWidth(grid)
	cWidth = 0
	for i in 0..grid.columns.length - 1
		column = grid.columns[i]
		if column.visible
			cWidth += column.width
		end
	end
	return cWidth
end

#获取内容的高度 
#grid:表格
def getGridContentHeight(grid)
	cHeight = 0
	for i in 0..grid.rows.length - 1
		row = grid.rows[i]
		if row.visible
			cHeight += grid.rowHeight
		end
	end
	return cHeight
end

#绘制列 
#grid:表格 
#column:列
#paint:绘图对象 
#left:左侧坐标 
#top:上方坐标 
#right:右侧坐标 
#bottom:下方坐标
def drawGridColumn(grid, column, paint, left, top, right, bottom)
	tSize = paint.textSize(column.text, column.font)
	#绘制背景
	if column.backColor != "none"
		paint.fillRect(column.backColor, left, top, right, bottom)
	end
	#绘制边线
	if column.borderColor != "none"
		paint.drawRect(column.borderColor, 1, 0, left, top, right, bottom)
	end
	paint.drawText(column.text, column.textColor, column.font, left + (column.width - tSize.cx) / 2, top + grid.headerHeight / 2 - tSize.cy / 2)
	#绘制升序箭头
	if column.sort == "asc"
		cR = (bottom - top) / 4
		oX = right - cR * 2
		oY = top + (bottom - top) / 2
		drawPoints = []
		drawPoints.push(FCPoint.new(oX, oY - cR))
		drawPoints.push(FCPoint.new(oX - cR, oY + cR))
		drawPoints.push(FCPoint.new(oX + cR, oY + cR))
		paint.fillPolygon(column.textColor, drawPoints)
	#绘制降序箭头
	elsif column.sort == "desc"
		cR = (bottom - top) / 4
		oX = right - cR * 2
		oY = top + (bottom - top) / 2
		drawPoints = []
		drawPoints.push(FCPoint.new(oX, oY + cR))
		drawPoints.push(FCPoint.new(oX - cR, oY - cR))
		drawPoints.push(FCPoint.new(oX + cR, oY - cR))
		paint.fillPolygon(column.textColor, drawPoints) 
	end
end

#绘制表格 
#grid:表格
#paint:绘图对象 
#clipRect:裁剪区域
def drawGrid(grid, paint, clipRect)
	cTop = -grid.scrollV + grid.headerHeight
	colLeft = 0
	for i in 0..grid.views.length - 1
		grid.views[i].visible = false
	end
	#重置列头
	for i in 0..grid.columns.length - 1
		column = grid.columns[i]
		if column.widthStr.length > 0
			newWidthStr = column.widthStr.gsub("%", "")
			grid.columns[i].width = ((newWidthStr).to_f * grid.size.cx / 100).to_i
		end
		colRect = FCRect.new(colLeft, 0, colLeft + grid.columns[i].width, grid.headerHeight)
		column.bounds = colRect
		column.index = i
		colLeft += column.width
	end
	for i in 0..grid.rows.length - 1
		row = grid.rows[i]
		row.index = i
		if row.visible
			rTop = cTop
			rBottom = cTop + grid.rowHeight
			#绘制非冻结列
			if rBottom >= 0 && cTop <= grid.size.cy
				for j in 0..row.cells.length - 1
					cell = row.cells[j]
					gridColumn = cell.column
					if gridColumn == nil
						gridColumn = grid.columns[j]
					end
					if gridColumn.visible
						if gridColumn.frozen == false
							cellWidth = gridColumn.width
							colSpan = cell.colSpan
							if colSpan > 1
								for n in 1..colSpan - 1
									spanColumn = grid.columns[gridColumn.index + n]
									if spanColumn != nil && spanColumn.visible
										cellWidth += spanColumn.width
									end
								end
							end
							cellHeight = grid.rowHeight
							rowSpan = cell.rowSpan
							if rowSpan > 1
								for n in 1..rowSpan - 1
									spanRow = grid.rows[i + n]
									if spanRow != nil && spanRow.visible
										cellHeight += grid.rowHeight
									end
								end
							end
							cRect = FCRect.new(gridColumn.bounds.left - grid.scrollH, rTop, gridColumn.bounds.left + cellWidth - grid.scrollH, rTop + cellHeight)
							if cRect.right >= 0 && cRect.left < grid.size.cx
								if grid.paint.onPaintGridCell != nil
									grid.paint.onPaintGridCell.call(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom)
								else
									drawGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom)
								end
								if cell.view != nil
									cell.view.visible = true
									cell.view.location = FCPoint.new(cRect.left + grid.scrollH, cRect.top + grid.scrollV)
									cell.view.size = FCSize.new(cRect.right - cRect.left, cRect.bottom - cRect.top)
								end
							end
						end
					end
				end
			end
			#绘制冻结列
			if rBottom >= 0 && cTop <= grid.size.cy
				for j in 0..row.cells.length - 1
					cell = row.cells[j]
					gridColumn = cell.column
					if gridColumn == nil
						gridColumn = grid.columns[j]
					end
					if gridColumn.visible
						if gridColumn.frozen
							cellWidth = gridColumn.width
							colSpan = cell.colSpan
							if colSpan > 1
								for n in 1..colSpan - 1
									spanColumn = grid.columns[gridColumn.index + n]
									if spanColumn != nil && spanColumn.visible
										cellWidth += spanColumn.width
									end
								end
							end
							cellHeight = grid.rowHeight
							rowSpan = cell.rowSpan
							if rowSpan > 1
								for n in 1..rowSpan - 1
									spanRow = grid.rows[i + n]
									if spanRow != nil && spanRow.visible
										cellHeight += grid.rowHeight
									end
								end
							end
							cRect = FCRect.new(gridColumn.bounds.left, rTop, gridColumn.bounds.left + cellWidth, rTop + cellHeight)
							if cRect.right >= 0 and cRect.left < grid.size.cx
								if grid.paint.onPaintGridCell != nil
									grid.paint.onPaintGridCell.call(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom)
								else
									drawGridCell(grid, row, gridColumn, cell, paint, cRect.left, cRect.top, cRect.right, cRect.bottom)
								end
								if cell.view != nil
									cell.view.visible = true
									cell.view.location = FCPoint.new(cRect.left + grid.scrollH, cRect.top + grid.scrollV)
									cell.view.size = FCSize.new(cRect.right - cRect.left, cRect.bottom - cRect.top)
								end
							end
						end
					end
				end
			end
			if cTop > grid.size.cy
				break
			end
			cTop += grid.rowHeight
		end
	end
end

#绘制表格的滚动条 
#grid:表格 
#paint:绘图对象
#clipRect:裁剪区域
def drawGridScrollBar(grid, paint, clipRect)
	grid.hScrollIsVisible = false
	grid.vScrollIsVisible = false
	if grid.headerHeight > 0
		cLeft = -grid.scrollH
		#绘制非冻结列
		for i in 0..grid.columns.length - 1
			gridColumn = grid.columns[i]
			if gridColumn.visible
				if gridColumn.frozen == false
					if grid.paint.onPaintGridColumn != nil
						grid.paint.onPaintGridColumn.call(grid, gridColumn, paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight)
					else
						drawGridColumn(grid, gridColumn, paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight)
					end
				end
				cLeft += gridColumn.width
			end
		end
		cLeft = 0
		#绘制冻结列
		for i in 0..grid.columns.length - 1
			gridColumn = grid.columns[i]
			if gridColumn.visible
				if gridColumn.frozen
					if grid.paint.onPaintGridColumn != nil
						grid.paint.onPaintGridColumn.call(grid, gridColumn, paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight)
					else
						drawGridColumn(grid, gridColumn, paint, cLeft, 0, cLeft + gridColumn.width, grid.headerHeight)
					end
				end
				cLeft += gridColumn.width
			end
		end
	end
	#绘制横向滚动条
	if grid.showHScrollBar
		contentWidth = getGridContentWidth(grid)
		if contentWidth > 0 && contentWidth > grid.size.cx
			sLeft = grid.size.cx * grid.scrollH / contentWidth
			sRight = grid.size.cx * (grid.scrollH + grid.size.cx) / contentWidth
			if sRight - sLeft < grid.scrollSize
				sRight = sLeft + grid.scrollSize
			end
			if paint.touchMoveView == grid && (grid.hoverScrollHButton || grid.downScrollHButton)
				paint.fillRect(grid.scrollBarHoveredColor, sLeft, grid.size.cy - grid.scrollSize, sRight, grid.size.cy)
			else
				paint.fillRect(grid.scrollBarColor, sLeft, grid.size.cy - grid.scrollSize, sRight, grid.size.cy)
			end
			grid.hScrollIsVisible = true
		end
	end
	#绘制纵向滚动条
	if grid.showVScrollBar
		contentHeight = getGridContentHeight(grid)
		if contentHeight > 0 && contentHeight > grid.size.cy - grid.headerHeight && contentHeight > 0 && grid.size.cy - grid.headerHeight - grid.scrollSize > 0
			sTop = grid.headerHeight + (grid.size.cy - grid.headerHeight - grid.scrollSize) * grid.scrollV / contentHeight
			sBottom = sTop + (grid.size.cy - grid.headerHeight - grid.scrollSize) * (grid.size.cy - grid.headerHeight - grid.scrollSize) / contentHeight
			if sBottom - sTop < grid.scrollSize
				sBottom = sTop + grid.scrollSize
			end
			if paint.touchMoveView == grid && (grid.hoverScrollVButton || grid.downScrollVButton)
				paint.fillRect(grid.scrollBarHoveredColor, grid.size.cx - grid.scrollSize, sTop, grid.size.cx, sBottom)
			else
				paint.fillRect(grid.scrollBarColor, grid.size.cx - grid.scrollSize, sTop, grid.size.cx, sBottom)
			end
			grid.vScrollIsVisible = true
		end
	end
end

#表格的鼠标移动方法 
#grid: 表格 
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
def touchMoveGrid(grid, firstTouch, firstPoint, secondTouch, secondPoint)
	grid.hoverScrollHButton = false
	grid.hoverScrollVButton = false
	if grid.paint.resizeColumnState != 0
		gridColumn = grid.columns[grid.paint.resizeColumnIndex]
		newWidth = grid.paint.resizeColumnBeginWidth + (firstPoint.x - grid.startPoint.x)
		if newWidth > 10
			gridColumn.width = newWidth
		end
		return
	end
	mp = firstPoint
	if firstTouch
		if grid.showHScrollBar || grid.showVScrollBar
			#判断横向滚动条
			if grid.downScrollHButton
				contentWidth = getGridContentWidth(grid)
				subX = contentWidth * (mp.x - grid.startPoint.x) / grid.size.cx
				newScrollH = grid.startScrollH + subX
				if newScrollH < 0
					newScrollH = 0
				elsif newScrollH > contentWidth - grid.size.cx
					newScrollH = contentWidth - grid.size.cx
				end
				grid.scrollH = newScrollH
				grid.paint.cancelClick = true
				return
			#判断纵向滚动条
			elsif grid.downScrollVButton
				contentHeight = getGridContentHeight(grid)
				subY = contentHeight * (mp.y - grid.startPoint.y) / (grid.size.cy - grid.headerHeight - grid.scrollSize)
				newScrollV = grid.startScrollV + subY
				if newScrollV < 0
					newScrollV = 0
				elsif newScrollV > contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize)
					newScrollV = contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize)
				end
				grid.scrollV = newScrollV
				grid.paint.cancelClick = true
				return
			end
		end
		#处理拖动
		if grid.allowDragScroll
			contentWidth = getGridContentWidth(grid)
			if contentWidth > grid.size.cx - grid.scrollSize
				subX = grid.startPoint.x - mp.x
				newScrollH = grid.startScrollH + subX
				if newScrollH < 0
					newScrollH = 0
				elsif newScrollH > contentWidth - grid.size.cx
					newScrollH = contentWidth - grid.size.cx
				end
				grid.scrollH = newScrollH
				if subX.abs > 5
					grid.paint.cancelClick = true
				end
			end
			contentHeight = getGridContentHeight(grid)
			if contentHeight > grid.size.cy - grid.headerHeight - grid.scrollSize
				subY = grid.startPoint.y - mp.y
				newScrollV = grid.startScrollV + subY
				if newScrollV < 0
					newScrollV = 0
				elsif newScrollV > contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize)
					newScrollV = contentHeight - (grid.size.cy - grid.headerHeight - grid.scrollSize)
				end
				grid.scrollV = newScrollV
				if subY.abs > 5
					grid.paint.cancelClick = true
				end
			end
		end
	else
		#判断横向滚动条
		if grid.showHScrollBar
			contentWidth = getGridContentWidth(grid)
			if contentWidth > 0 && contentWidth > grid.size.cx - grid.scrollSize
				sLeft = grid.size.cx * grid.scrollH / contentWidth
				sRight = grid.size.cx * (grid.scrollH + grid.size.cx) / contentWidth
				if sRight - sLeft < grid.scrollSize
					sRight = sLeft + grid.scrollSize
				end
				if mp.x >= sLeft && mp.x <= sRight && mp.y >= grid.size.cy - grid.scrollSize && mp.y <= grid.size.cy
					grid.hoverScrollHButton = true
					return
				else
					grid.hoverScrollHButton = false
				end
			end
		end
		#判断纵向滚动条
		if grid.showVScrollBar
			contentHeight = getGridContentHeight(grid)
			if contentHeight > 0 && contentHeight > grid.size.cy - grid.headerHeight - grid.scrollSize
				sTop = grid.headerHeight + (grid.size.cy - grid.headerHeight - grid.scrollSize) * grid.scrollV / contentHeight
				sBottom = grid.headerHeight + (grid.size.cy - grid.headerHeight - grid.scrollSize) * (grid.scrollV + (grid.size.cy - grid.headerHeight - grid.scrollSize)) / contentHeight
				if sBottom - sTop < grid.scrollSize
					sBottom = sTop + grid.scrollSize
				end
				if mp.x >= grid.size.cx - grid.scrollSize && mp.x <= grid.size.cx && mp.y >= sTop && mp.y <= sBottom
					grid.hoverScrollVButton = true
					return
				else
					grid.hoverScrollVButton = false
				end
			end
		end
	end
end

#表格的鼠标按下方法 
#grid: 表格 
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks:点击次数
def touchDownGrid(grid, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	mp = firstPoint
	grid.startPoint = mp
	grid.downScrollHButton = false
	grid.downScrollVButton = false
	grid.hoverScrollHButton = false
	grid.hoverScrollVButton = false
	#判断横向滚动条
	if grid.showHScrollBar
		contentWidth = getGridContentWidth(grid)
		if contentWidth > 0 && contentWidth > grid.size.cx - grid.scrollSize
			sLeft = grid.size.cx * grid.scrollH / contentWidth
			sRight = grid.size.cx * (grid.scrollH + grid.size.cx) / contentWidth
			if sRight - sLeft < grid.scrollSize
				sRight = sLeft + grid.scrollSize
			end
			if mp.x >= sLeft && mp.x <= sRight && mp.y >= grid.size.cy - grid.scrollSize && mp.y <= grid.size.cy
				grid.downScrollHButton = true
				grid.startScrollH = grid.scrollH
				return
			end
		end
	end
	#判断纵向滚动条
	if grid.showVScrollBar
		contentHeight = getGridContentHeight(grid)
		if contentHeight > 0 && contentHeight > grid.size.cy - grid.headerHeight - grid.scrollSize
			sTop = grid.headerHeight + (grid.size.cy - grid.headerHeight - grid.scrollSize) * grid.scrollV / contentHeight
			sBottom = grid.headerHeight + (grid.size.cy - grid.headerHeight - grid.scrollSize) * (grid.scrollV + (grid.size.cy - grid.headerHeight - grid.scrollSize)) / contentHeight
			if sBottom - sTop < grid.scrollSize
				sBottom = sTop + grid.scrollSize
			end
			if mp.x >= grid.size.cx - grid.scrollSize && mp.x <= grid.size.cx && mp.y >= sTop && mp.y <= sBottom
				grid.downScrollVButton = true
				grid.startScrollV = grid.scrollV
				return
			end
		end
	end
	if grid.allowDragScroll
		grid.startScrollH = grid.scrollH
		grid.startScrollV = grid.scrollV
	end
	colLeft = 0
	#重置列
	for i in 0..grid.columns.length - 1
		column = grid.columns[i]
		colRect = FCRect.new(colLeft, 0, colLeft + grid.columns[i].width, grid.headerHeight)
		column.bounds = colRect
		column.index = i
		colLeft += column.width
	end
	grid.paint.resizeColumnState = 0
	grid.paint.resizeColumnBeginWidth = 0
	if grid.headerHeight > 0 && mp.y <= grid.headerHeight
		for i in 0..grid.columns.length - 1
			gridColumn = grid.columns[i]
			if gridColumn.visible
				bounds = gridColumn.bounds
				if mp.x >= bounds.left - grid.scrollH && mp.x <= bounds.right - grid.scrollH
					if gridColumn.index > 0 && mp.x < bounds.left + 5 - grid.scrollH
						grid.paint.resizeColumnState = 1
						grid.paint.resizeColumnBeginWidth = grid.columns[gridColumn.index - 1].bounds.right - grid.columns[gridColumn.index - 1].bounds.left
						grid.paint.resizeColumnIndex = gridColumn.index - 1
						return
					elsif mp.x > bounds.right - 5 - grid.scrollH
						grid.paint.resizeColumnState = 2
						grid.paint.resizeColumnBeginWidth = bounds.right - bounds.left
						grid.paint.resizeColumnIndex = gridColumn.index
						return
					end
					break
				end
			end
		end
	end
	
	cTop = -grid.scrollV + grid.headerHeight
	colLeft = 0
	#重置列
	for i in 0..grid.columns.length - 1
		column = grid.columns[i]
		colRect = FCRect.new(colLeft, 0, colLeft + grid.columns[i].width, grid.headerHeight)
		column.bounds = colRect
		column.index = i
		colLeft += column.width
	end
	#判断列头
	if grid.headerHeight > 0 && firstPoint.y <= grid.headerHeight
		cLeft = 0
		for i in 0..grid.columns.length - 1
			gridColumn = grid.columns[i]
			if gridColumn.visible
				if gridColumn.frozen
					if firstPoint.x >= cLeft && firstPoint.x <= cLeft + gridColumn.width
						for j in 0..grid.columns.length - 1
							tColumn = grid.columns[j]
							if tColumn == gridColumn
								if tColumn.allowSort
									if tColumn.sort == "none" || tColumn.sort == "desc"
										tColumn.sort = "asc"
									else
										tColumn.sort = "desc"
									end
								else
									tColumn.sort = "none"
								end
							else
								tColumn.sort = "none"
							end
						end
						if grid.paint.onClickGridColumn != nil
							grid.paint.onClickGridColumn.call(grid, gridColumn, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
						end
						return
					end
				end
				cLeft += gridColumn.width
			end
		end
		cLeft = -grid.scrollH
		for i in 0..grid.columns.length - 1
			gridColumn = grid.columns[i]
			if gridColumn.visible
				if gridColumn.frozen == false
					if firstPoint.x >= cLeft && firstPoint.x <= cLeft + gridColumn.width
						for j in 0..grid.columns.length - 1
							tColumn = grid.columns[j]
							if tColumn == gridColumn
								if tColumn.allowSort
									if tColumn.sort == "none" || tColumn.sort == "desc"
										tColumn.sort = "asc"
									else
										tColumn.sort = "desc"
									end
								else
									tColumn.sort = "none"
								end
							else
								tColumn.sort = "none"
							end
						end
						if grid.paint.onClickGridColumn != nil
							grid.paint.onClickGridColumn.call(grid, gridColumn, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
						end
						return
					end
				end
				cLeft += gridColumn.width
			end
		end
	end
	for i in 0..grid.rows.length - 1
		row = grid.rows[i]
		if row.visible
			rTop = cTop
			rBottom = cTop + grid.rowHeight
			if rBottom >= 0 && cTop <= grid.size.cy
				for j in 0..row.cells.length - 1
					cell = row.cells[j]
					gridColumn = cell.column
					if gridColumn == nil
						gridColumn = grid.columns[j]
					end
					if gridColumn.visible
						if gridColumn.frozen
							cellWidth = gridColumn.width
							colSpan = cell.colSpan
							if colSpan > 1
								for n in 1..colSpan - 1
									spanColumn = grid.columns[gridColumn.index + n]
									if spanColumn != nil && spanColumn.visible
										cellWidth += spanColumn.width
									end
								end
							end
							cellHeight = grid.rowHeight
							rowSpan = cell.rowSpan
							if rowSpan > 1
								for n in 1..rowSpan - 1
									spanRow = grid.rows[i + n]
									if spanRow != nil && spanRow.visible
										cellHeight += grid.rowHeight
									end
								end
							end
							cRect = FCRect.new(gridColumn.bounds.left, rTop, gridColumn.bounds.left + cellWidth, rTop + cellHeight)
							if cRect.right >= 0 && cRect.left < grid.size.cx
								if firstPoint.x >= cRect.left && firstPoint.x <= cRect.right && firstPoint.y >= cRect.top && firstPoint.y <= cRect.bottom
									for s in 0..grid.rows.length - 1
										subRow = grid.rows[s]
										if subRow == row
											subRow.selected = true
										else
											subRow.selected = false
										end
									end
									if grid.paint.onClickGridCell != nil
										grid.paint.onClickGridCell.call(grid, row, gridColumn, cell, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
									end
									return
								end
							end
						end
					end
				end
			end
			if rBottom >= 0 && cTop <= grid.size.cy
				for j in 0..row.cells.length - 1
					cell = row.cells[j]
					gridColumn = cell.column
					if gridColumn == nil
						gridColumn = grid.columns[j]
					end
					if gridColumn.visible
						if gridColumn.frozen == false
							cellWidth = gridColumn.width
							colSpan = cell.colSpan
							if colSpan > 1
								for n in 1..colSpan - 1
									spanColumn = grid.columns[gridColumn.index + n]
									if spanColumn != nil && spanColumn.visible
										cellWidth += spanColumn.width
									end
								end
							end
							cellHeight = grid.rowHeight
							rowSpan = cell.rowSpan
							if rowSpan > 1
								for n in 1..rowSpan - 1
									spanRow = grid.rows[i + n]
									if spanRow != nil && spanRow.visible
										cellHeight += grid.rowHeight
									end
								end
							end
							cRect = FCRect.new(gridColumn.bounds.left - grid.scrollH, rTop, gridColumn.bounds.left + cellWidth - grid.scrollH, rTop + cellHeight)
							if cRect.right >= 0 && cRect.left < grid.size.cx
								if firstPoint.x >= cRect.left && firstPoint.x <= cRect.right && firstPoint.y >= cRect.top && firstPoint.y <= cRect.bottom
									for s in 0..grid.rows.length - 1
										subRow = grid.rows[s]
										if subRow == row
											subRow.selected = true
										else
											subRow.selected = false
										end
									end
									if grid.paint.onClickGridCell != nil
										grid.paint.onClickGridCell.call(grid, row, gridColumn, cell, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
									end
									return
								end
							end
						end
					end
				end
			end
			if cTop > grid.size.cy
				break
			end
			cTop += grid.rowHeight
		end
	end
end

#表格的鼠标抬起方法 
#grid: 表格 
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks:点击次数
def touchUpGrid(grid, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	grid.downScrollHButton = false
	grid.downScrollVButton = false
	grid.hoverScrollHButton = false
	grid.hoverScrollVButton = false
	if grid.paint.resizeColumnState != 0
		grid.paint.resizeColumnState = 0
		return
	end
end

#获取内容的宽度
#tree:树
def getTreeContentWidth(tree)
	cWidth = 0
	for i in 0..tree.columns.length - 1
		column = tree.columns[i]
		if column.visible
			cWidth += column.width
		end
	end
	return cWidth
end

#获取内容的高度
#tree:树
def getTreeContentHeight(tree)
	cHeight = 0
	for i in 0..tree.rows.length - 1
		row = tree.rows[i]
		if row.visible
			cHeight += tree.rowHeight
		end
	end
	return cHeight
end

#绘制滚动条
#tree:树
#paint:绘图对象
#clipRect:裁剪区域
def drawTreeScrollBar(tree, paint, clipRect)
	tree.hScrollIsVisible = false
	tree.vScrollIsVisible = false
	#判断横向滚动条
	if tree.showHScrollBar
		contentWidth = getTreeContentWidth(tree)
		if contentWidth > 0 && contentWidth > tree.size.cx
			sLeft = tree.size.cx * tree.scrollH / contentWidth
			sRight = tree.size.cx * (tree.scrollH + tree.size.cx) / contentWidth
			if sRight - sLeft < tree.scrollSize
				sRight = sLeft + tree.scrollSize
			end
			if paint.touchMoveView == tree && (tree.hoverScrollHButton || tree.downScrollHButton)
				paint.fillRect(tree.scrollBarHoveredColor, sLeft, tree.size.cy - tree.scrollSize, sRight, tree.size.cy)
			else
				paint.fillRect(tree.scrollBarColor, sLeft, tree.size.cy - tree.scrollSize, sRight, tree.size.cy)
			end
			tree.hScrollIsVisible = true
		end
	end
	#判断纵向滚动条
	if tree.showVScrollBar
		contentHeight = getTreeContentHeight(tree)	
		if contentHeight > 0 && contentHeight > tree.size.cy
			sTop = tree.headerHeight + (tree.size.cy - tree.headerHeight - tree.scrollSize) * tree.scrollV / contentHeight
			sBottom = sTop + (tree.size.cy - tree.headerHeight - tree.scrollSize) * (tree.size.cy - tree.headerHeight) / contentHeight
			if sBottom - sTop < tree.scrollSize
				sBottom = sTop + tree.scrollSize
			end
			if paint.touchMoveView == tree && (tree.hoverScrollVButton || tree.downScrollVButton)
				paint.fillRect(tree.scrollBarHoveredColor, tree.size.cx - tree.scrollSize, sTop, tree.size.cx, sBottom)
			else
				paint.fillRect(tree.scrollBarColor, tree.size.cx - tree.scrollSize, sTop, tree.size.cx, sBottom)
			end
			tree.vScrollIsVisible = true
		end
	end
end

#绘制单元格
#tree:树
#row:行
#column:列
#node:节点
#paint:绘图对象
#left:左侧坐标
#top:上方坐标
#right:右侧坐标
#bottom:下方坐标
def drawTreeNode(tree, row, column, node, paint, left, top, right, bottom)
	#绘制背景
	if node.backColor != "none"
		paint.fillRect(node.backColor, left, top, right, bottom)
	end
	if node.value != nil
		tSize = paint.textSize(node.value, node.font)
		tLeft = left + 2 + getTotalIndent(node)
		wLeft = tLeft
		cR = tree.checkBoxWidth / 3
		#绘制复选框
		if tree.showCheckBox
			wLeft += tree.checkBoxWidth
			if node.checked
				paint.fillRect(node.textColor, tLeft + (tree.checkBoxWidth - cR) / 2, top + (tree.rowHeight - cR) / 2, tLeft + (tree.checkBoxWidth + cR) / 2, top + (tree.rowHeight + cR) / 2)
			else
				paint.drawRect(node.textColor, 1, 0, tLeft + (tree.checkBoxWidth - cR) / 2, top + (tree.rowHeight - cR) / 2, tLeft + (tree.checkBoxWidth + cR) / 2, top + (tree.rowHeight + cR) / 2)
			end
		end
		#绘制箭头
		if node.childNodes.length > 0
			drawPoints = []
			if node.collapsed
				drawPoints.push(FCPoint.new(wLeft + (tree.collapsedWidth + cR) / 2, top + tree.rowHeight / 2))
				drawPoints.push(FCPoint.new(wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight - cR) / 2))
				drawPoints.push(FCPoint.new(wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight + cR) / 2))
			else
				drawPoints.push(FCPoint.new(wLeft + (tree.collapsedWidth - cR) / 2, top + (tree.rowHeight - cR) / 2))
				drawPoints.push(FCPoint.new(wLeft + (tree.collapsedWidth + cR) / 2, top + (tree.rowHeight - cR) / 2))
				drawPoints.push(FCPoint.new(wLeft + tree.collapsedWidth / 2, top + (tree.rowHeight + cR) / 2))
			end
			paint.fillPolygon(node.textColor, drawPoints)
			wLeft += tree.collapsedWidth
		end
		#绘制文字
		if tSize.cx > column.width
			paint.drawTextAutoEllipsis(node.value.to_s, node.textColor, node.font, wLeft, top + tree.rowHeight / 2 - tSize.cy / 2, wLeft + column.width, top + tree.rowHeight / 2 - tSize.cy / 2)
		else
			paint.drawText(node.value.to_s, node.textColor, node.font, wLeft, top + tree.rowHeight / 2 - tSize.cy / 2)
		end
	end
end

#更新行的索引
#tree:树
def updateTreeRowIndex(tree)
	for i in 0..tree.rows.length - 1
		tree.rows[i].index = i
	end
end

#绘制树
#tree:树
#paint:绘图对象
#clipRect:裁剪区域
def drawTree(tree, paint, clipRect)
	cLeft = -tree.scrollH
	cTop = -tree.scrollV + tree.headerHeight
	colLeft = 0
	#重置列头
	for i in 0..tree.columns.length - 1
		column = tree.columns[i]
		if column.widthStr.length > 0
			newWidthStr = column.widthStr.gsub("%", "")
			tree.columns[i].width = ((newWidthStr).to_f * tree.size.cx / 100).to_i
		end
		colRect = FCRect.new(colLeft, 0, colLeft + tree.columns[i].width, tree.headerHeight)
		tree.columns[i].bounds = colRect
		tree.columns[i].index = i
		colLeft += tree.columns[i].width
	end
	updateTreeRowIndex(tree)
	for i in 0..tree.rows.length - 1
		row = tree.rows[i]
		if row.visible
			rTop = cTop
			rBottom = cTop + tree.rowHeight
			if rBottom >= 0 && cTop <= tree.size.cy
				for j in 0..row.cells.length - 1
					node = row.cells[j]
					treeColumn = node.column
					if treeColumn == nil
						treeColumn = tree.columns[j]
					end
					if treeColumn.visible
						nodeWidth = treeColumn.width
						nodeHeight = tree.rowHeight
						cRect = FCRect.new(treeColumn.bounds.left - tree.scrollH, rTop, treeColumn.bounds.left + nodeWidth - tree.scrollH, rTop + nodeHeight)
						if cRect.right >= 0 && cRect.left < tree.size.cx
							if tree.paint.onPaintTreeNode != nil
								tree.paint.onPaintTreeNode.call(tree, row, treeColumn, node, paint, cRect.left, cRect.top, cRect.right, cRect.bottom)
							else
								drawTreeNode(tree, row, treeColumn, node, paint, cRect.left, cRect.top, cRect.right, cRect.bottom)
							end
						end
					end
				end
			end
			if cTop > tree.size.cy
				break
			end
			cTop += tree.rowHeight
		end
	end
end

#获取最后一行的索引 
#node:树节点
def getTreeLastNodeRowIndex(node)
	rowIndex = node.row.index
	for i in 0..node.childNodes.length - 1
		rIndex = getTreeLastNodeRowIndex(node.childNodes[i])
		if rowIndex < rIndex
			rowIndex = rIndex
		end
	end
	return rowIndex
end

#添加节点
#tree:树
#node:要添加的节点
#parentNode:父节点
def appendTreeNode(tree, node, parentNode)
	if parentNode == nil
		newRow = FCTreeRow.new()
		tree.rows.push(newRow)
		node.row = newRow
		newRow.cells.push(node)
		tree.childNodes.push(node)
	else
		newRow = FCTreeRow.new()
		if parentNode.childNodes.length == 0
			tree.rows.insert(parentNode.row.index + 1, newRow)
		else
			tree.rows.insert(getTreeLastNodeRowIndex(parentNode) + 1, newRow)
		end
		node.parentNode = parentNode
		node.indent = tree.indent
		node.row = newRow
		newRow.cells.push(node)
		parentNode.childNodes.push(node)
		if parentNode.collapsed
			newRow.visible = false
		end
	end
	updateTreeRowIndex(tree)
end

#移除节点
#tree:树
#node:要添加的节点
def removeTreeNode(tree, node)
	if node.parentNode == nil
		nodesSize = tree.childNodes.length
		for i in 0..nodesSize - 1
			if tree.childNodes[i] == node
				tree.childNodes.delete_at(i)
				break
			end
		end
	else
		nodesSize = node.parentNode.childNodes.length
		for i in 0..nodesSize - 1
			if node.parentNode.childNodes[i] == node
				node.parentNode.childNodes.delete_at(i)
				break
			end
		end
	end
	tree.rows.delete_at(node.row.index)
	updateTreeRowIndex(tree)
end

#展开或折叠节点
#node:节点
#visible:是否可见
def hideOrShowTreeNode(node, visible)
	if node.childNodes.length > 0
		for i in 0..node.childNodes.length - 1
			node.childNodes[i].row.visible = visible
			hideOrShowTreeNode(node.childNodes[i], visible)
		end
	end
end

#展开或折叠节点
#node:节点
#checked:是否选中
def checkOrUnCheckTreeNode(node, checked)
	node.checked = checked
	if node.childNodes.length > 0
		for i in 0..node.childNodes.length - 1
			checkOrUnCheckTreeNode(node.childNodes[i], checked)
		end
	end
end

#树的鼠标滚轮方法
#tree:树
#delta:滚轮值
def touchWheelTree(tree, delta)
	oldScrollV = tree.scrollV
	if delta > 0
		oldScrollV -= tree.rowHeight
	elsif delta < 0
		oldScrollV += tree.rowHeight
	end
	contentHeight = getTreeContentHeight(tree)
	if contentHeight < tree.size.cy
		tree.scrollV = 0
	else
		if oldScrollV < 0
			oldScrollV = 0
		elsif oldScrollV > contentHeight - tree.size.cy + tree.headerHeight + tree.scrollSize
			oldScrollV = contentHeight - tree.size.cy + tree.headerHeight + tree.scrollSize
		end
		tree.scrollV = oldScrollV
	end
end

#树的鼠标移动方法
#tree: 树
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
def touchMoveTree(tree, firstTouch, firstPoint, secondTouch, secondPoint)
	tree.hoverScrollHButton = false
	tree.hoverScrollVButton = false
	mp = firstPoint
	if firstTouch
		if tree.showHScrollBar || tree.showVScrollBar
			#判断横向滚动
			if tree.downScrollHButton
				contentWidth = getTreeContentWidth(tree)
				subX = contentWidth * (mp.x - tree.startPoint.x) / tree.size.cx
				newScrollH = tree.startScrollH + subX
				if newScrollH < 0
					newScrollH = 0
				elsif(newScrollH > contentWidth - tree.size.cx)
					newScrollH = contentWidth - tree.size.cx
				end
				tree.scrollH = newScrollH
				tree.paint.cancelClick = true
				return
			#判断纵向滚动
			elsif tree.downScrollVButton
				contentHeight = getTreeContentHeight(tree)
				subY = contentHeight * (mp.y - tree.startPoint.y) / (tree.size.cy - tree.headerHeight - tree.scrollSize)
				newScrollV = tree.startScrollV + subY
				if newScrollV < 0
					newScrollV = 0
				elsif (newScrollV > contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize))
					newScrollV = contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize)
				end
				tree.scrollV = newScrollV
				tree.paint.cancelClick = true
				return
			end
		end
		#判断拖动
		if tree.allowDragScroll
			contentWidth = getTreeContentWidth(tree)
			if contentWidth > tree.size.cx
				subX = tree.startPoint.x - mp.x
				newScrollH = tree.startScrollH + subX
				if newScrollH < 0
					newScrollH = 0
				elsif (newScrollH > contentWidth - tree.size.cx)
					newScrollH = contentWidth - tree.size.cx
				end
				tree.scrollH = newScrollH
				if subX.abs > 5
					tree.paint.cancelClick = true
				end
			end
			contentHeight = getTreeContentHeight(tree)
			if contentHeight > tree.size.cy
				subY = tree.startPoint.y - mp.y
				newScrollV = tree.startScrollV + subY
				if newScrollV < 0
					newScrollV = 0
				elsif newScrollV > contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize)
					newScrollV = contentHeight - (tree.size.cy - tree.headerHeight - tree.scrollSize)
				end
				tree.scrollV = newScrollV
				if subY.abs > 5
					tree.paint.cancelClick = true
				end
			end
		end
	else
		#判断横向滚动
		if tree.showHScrollBar
			contentWidth = getTreeContentWidth(tree)
			if contentWidth > 0 && contentWidth > tree.size.cx
				sLeft = tree.size.cx * tree.scrollH / contentWidth
				sRight = tree.size.cx * (tree.scrollH + tree.size.cx) / contentWidth
				if sRight - sLeft < tree.scrollSize
					sRight = sLeft + tree.scrollSize
				end
				if mp.x >= sLeft && mp.x <= sRight && mp.y >= tree.size.cy - tree.scrollSize && mp.y <= tree.size.cy
					tree.hoverScrollHButton = true
					return
				else
					tree.hoverScrollHButton = false
				end
			end
		end
		#判断纵向滚动
		if tree.showVScrollBar
			contentHeight = getTreeContentHeight(tree)
			if contentHeight > 0 && contentHeight > tree.size.cy
				sTop = tree.headerHeight + (tree.size.cy - tree.headerHeight - tree.scrollSize) * tree.scrollV / contentHeight
				sBottom = tree.headerHeight + (tree.scrollV + (tree.size.cy - tree.headerHeight - tree.scrollSize) * (tree.size.cy - tree.headerHeight - tree.scrollSize)) / contentHeight
				if sBottom - sTop < tree.scrollSize
					sBottom = sTop + tree.scrollSize
				end
				if mp.x >= tree.size.cx - tree.scrollSize && mp.x <= tree.size.cx && mp.y >= sTop && mp.y <= sBottom
					tree.hoverScrollVButton = true
					return
				else
					tree.hoverScrollVButton = false
				end
			end
		end
	end
end				

#树的鼠标按下方法
#tree: 树
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks 点击次数
def touchDownTree(tree, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	mp = firstPoint
	tree.startPoint = mp
	tree.hoverScrollHButton = false
	tree.hoverScrollVButton = false
	tree.downScrollHButton = false
	tree.downScrollVButton = false
	#判断横向滚动
	if tree.showHScrollBar
		contentWidth = getTreeContentWidth(tree)
		if contentWidth > 0 && contentWidth > tree.size.cx
			sLeft = tree.size.cx * tree.scrollH / contentWidth
			sRight = tree.size.cx * (tree.scrollH + tree.size.cx) / contentWidth
			if sRight - sLeft < tree.scrollSize
				sRight = sLeft + tree.scrollSize
			end
			if mp.x >= sLeft && mp.x <= sRight && mp.y >= tree.size.cy - tree.scrollSize && mp.y <= tree.size.cy
				tree.downScrollHButton = true
				tree.startScrollH = tree.scrollH
				return
			end
		end
	end
	#判断纵向滚动
	if tree.showVScrollBar
		contentHeight = getTreeContentHeight(tree)
		if contentHeight > 0 && contentHeight > tree.size.cy
			sTop = tree.headerHeight + tree.scrollV / contentHeight * (tree.size.cy - tree.headerHeight - tree.scrollSize)
			sBottom = tree.headerHeight + (tree.size.cy - tree.headerHeight - tree.scrollSize) * (tree.scrollV + (tree.size.cy - tree.headerHeight - tree.scrollSize)) / contentHeight
			if sBottom - sTop < tree.scrollSize
				sBottom = sTop + tree.scrollSize
			end
			if mp.x >= tree.size.cx - tree.scrollSize && mp.x <= tree.size.cx && mp.y >= sTop && mp.y <= sBottom
				tree.downScrollVButton = true
				tree.startScrollV = tree.scrollV
				return
			end
		end
	end
	if tree.allowDragScroll
		tree.startScrollH = tree.scrollH
		tree.startScrollV = tree.scrollV
	end
	cLeft = -tree.scrollH
	cTop = -tree.scrollV + tree.headerHeight
	for i in 0..tree.rows.length - 1
		row = tree.rows[i]
		if row.visible
			if firstPoint.y >= cTop && firstPoint.y <= cTop + tree.rowHeight
				node = row.cells[0]
				tLeft = cLeft + 2 + getTotalIndent(node)
				wLeft = tLeft
				if tree.showCheckBox
					wLeft += tree.checkBoxWidth
					if firstPoint.x < wLeft
						if node.checked
							checkOrUnCheckTreeNode(node, false)
						else
							checkOrUnCheckTreeNode(node, true)
						end
						if tree.paint
							invalidateView(tree)
						end
						break
					end
				end
				if node.childNodes.length > 0
					wLeft += tree.collapsedWidth
					if firstPoint.x < wLeft
						if node.collapsed
							node.collapsed = false
							hideOrShowTreeNode(node, true)
						else
							node.collapsed = true
							hideOrShowTreeNode(node, false)
						end
						break
					end
				end
				if tree.paint.onClickTreeNode != nil
					tree.paint.onClickTreeNode.call(tree, node, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
				end
			end
			cTop += tree.rowHeight
		end
	end
end

#获取总的偏移量
#node:树节点
def getTotalIndent(node)
	if node.parentNode != nil
		return node.indent + getTotalIndent(node.parentNode)
	else
		return node.indent
	end
end

#树的鼠标抬起方法
#tree: 树
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks:点击次数
def touchUpTree(tree, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	tree.downScrollHButton = false
	tree.downScrollVButton = false
	tree.hoverScrollHButton = false
	tree.hoverScrollVButton = false
end

#计算直线参数 
#mp:坐标 
#x1:横坐标1 
#y1:纵坐标1 
#x2:横坐标2 
#y2:纵坐标2 
#oX:坐标起始X 
#oY:坐标起始Y
def lineXY(chart, x1, y1, x2, y2, oX, oY)
	chart.kChart = 0
	chart.bChart = 0
	if (x1 - oX) != (x2 - oX)
		chart.kChart = ((y2 - oY) - (y1 - oY)) / ((x2 - oX) - (x1 - oX))
		chart.bChart = (y1 - oY) - chart.kChart * (x1 - oX)
	end
end

#判断是否选中直线 
#mp:坐标 
#x1:横坐标1 
#y1:纵坐标1 
#x2:横坐标2 
#y2:纵坐标2
def selectLine(chart, mp, x1, y1, x2, y2)
	lineXY(chart, x1, y1, x2, y2, 0, 0)
    if chart.kChart != 0 || chart.bChart != 0
        if mp.y / (mp.x * chart.kChart + chart.bChart) >= 0.9 && mp.y / (mp.x * chart.kChart + chart.bChart) <= 1.1
            return true
		end
    else
        if mp.x >= x1 - chart.plotPointSizeChart && mp.x <= x1 + chart.plotPointSizeChart
            return true
		end
	end
    return false
end

#判断是否选中射线 
#mp:坐标 
#x1:横坐标1 
#y1:纵坐标1 
#x2:横坐标2 
#y2:纵坐标2
def selectRay(chart, mp, x1, y1, x2, y2)
	lineXY(chart, x1, y1, x2, y2, 0, 0)
	if chart.kChart != 0 || chart.bChart != 0
		if mp.y / (mp.x * chart.kChart + chart.bChart) >= 0.9 && mp.y / (mp.x * chart.kChart + chart.bChart) <= 1.1
			if x1 >= x2
				if mp.x > x1 + chart.plotPointSizeChart
					return false
				end
			elsif x1 < x2
				if mp.x < x1 - chart.plotPointSizeChart
					return false
				end
			end
			return true
		end
	else
		if mp.x >= x1 - chart.plotPointSizeChart && mp.x <= x1 + chart.plotPointSizeChart
			if y1 >= y2
				if mp.y <= y1 - chart.plotPointSizeChart
					return true
				end
			else
				if mp.y >= y1 - chart.plotPointSizeChart
					return true
				end
			end
		end
	end
	return false
end

#判断是否选中线段 
#mp:坐标 
#x1:横坐标1 
#y1:纵坐标1 
#x2:横坐标2 
#y2:纵坐标2
def selectSegment(chart, mp, x1, y1, x2, y2)
	lineXY(chart, x1, y1, x2, y2, 0, 0)
	smallX = x2
	if x1 <= x2
		smallX = x1
	end
	smallY = y2
	if y1 <= y2
		smallY = y1
	end
	bigX = x2
	if x1 > x2
		bigX = x1
	end
	bigY = y2
	if y1 > y2
		bigY = y1
	end
	if mp.x >= smallX - 2 && mp.x <= bigX + 2 && mp.y >= smallY - 2 && mp.y <= bigY + 2
		if chart.kChart != 0 || chart.bChart != 0
			if mp.y / (mp.x * chart.kChart + chart.bChart) >= 0.9 && mp.y / (mp.x * chart.kChart + chart.bChart) <= 1.1
				return true
			end
		else
			if mp.x >= x1 - chart.plotPointSizeChart && mp.x <= x1 + chart.plotPointSizeChart
				return true
			end
		end
	end
	return false
end

# 根据三点计算圆心 
#x1:横坐标 
#y1:纵坐标1 
#x2:横坐标2 
#y2:纵坐标2 
#x3:横坐标3 
#y3:纵坐标3
def ellipseOR(chart, x1, y1, x2, y2, x3, y3)
	chart.oXChart = ((y3 - y1) * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1) + (y2 - y1) * (y1 * y1 - y3 * y3 + x1 * x1 - x3 * x3)) / (2 * (x2 - x1) * (y3 - y1) - 2 * (x3 - x1) * (y2 - y1))
	chart.oYChart = ((x3 - x1) * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) + (x2 - x1) * (x1 * x1 - x3 * x3 + y1 * y1 - y3 * y3)) / (2 * (y2 - y1) * (x3 - x1) - 2 * (y3 - y1) * (x2 - x1))
	chart.rChart = Math.sqrt((x1 - chart.oXChart) * (x1 - chart.oXChart) + (y1 - chart.oYChart) * (y1 - chart.oYChart))
end

#判断点是否在椭圆上
#x:横坐标 
#y:纵坐标 
#oX:坐标起始X 
#oY:坐标起始Y 
#a:椭圆参数a 
#b:椭圆参数b
def ellipseHasPoint(x, y, oX, oY, a, b)
	x -= oX
	y -= oY
	if a == 0 && b == 0 && x == 0 && y == 0
		return true
	end
	if a == 0
		if x == 0 && y >= -b && y <= b
			return false
		end
	end
	if b == 0
		if y == 0 && x >= -a && x <= a
			return true
		end
	end
	if a != 0 && b != 0
		if (x * x) / (a * a) + (y * y) / (b * b) >= 0.8 && (x * x) / (a * a) + (y * y) / (b * b) <= 1.2
			return true
		end
	end
	return false
end

#计算线性回归 
#list:集合
def linearRegressionEquation(chart, list)
	result = 0
	sumX = 0
	sumY = 0
	sumUp = 0
	sumDown = 0
	xAvg = 0
	yAvg = 0
	chart.kChart = 0
	chart.bChart = 0
	length = list.length
	if length > 1
		for i in 0..length - 1
			sumX += i + 1
			sumY += list[i]
		end
		xAvg = sumX / length
		yAvg = sumY / length
		for i in 0..length - 1
			sumUp += (i + 1 - xAvg) * (list[i] - yAvg)
			sumDown += (i + 1 - xAvg) * (i + 1 - xAvg)
		end
		chart.kChart = sumUp / sumDown
		chart.bChart = yAvg - chart.kChart * xAvg
	end
	return result	  
end

#计算最大值 
#list:集合
def maxValue(list)
	length = list.length
	maxValue = 0
	for i in 0..length - 1
		if i == 0
			maxValue = list[i]
		else
			if (maxValue < list[i])
				maxValue = list[i]
			end
		end
	end
	return maxValue
end

#计算最小值 
#list:集合
def minValue(list)
	length = list.length
    minValue = 0
    for i in 0..length - 1
        if i == 0
            minValue = list[i]
        else
            if minValue > list[i]
                minValue = list[i]
			end
		end
	end
    return minValue
end

#计算平均值 
#list:集合
def avgValue(list)
	sumValue = 0
	length = list.length
	if length > 0
		for i in 0..length - 1
			sumValue += list[i]
		end
		return sumValue / length
	end
	return
end
	
#计算平行四边形参数 
#x1:横坐标1 
#y1:纵坐标1 
#x2:横坐标2 
#y2:纵坐标2 
#x3:横坐标3 
#y3:纵坐标3
def parallelogram(chart, x1, y1, x2, y2, x3, y3)
	chart.x4Chart = x1 + x3 - x2
	chart.y4Chart = y1 + y3 - y2
end

#计算斐波那契数列 
#index:索引
def fibonacciValue(index)
	if index < 1
		return 0
	else
		vList = []
		for i in 0..index - 1
			vList.push(0)
		end
		result = 0
		for i in 0..index - 1
			if i == 0 || i == 1
				vList[i] = 1
			else
				vList[i] = vList[i - 1] + vList[i - 2]
			end
		end
		result = vList[index - 1]
		return result
	end
end

# 获取百分比线的刻度 
#y1: 纵坐标1 
#y2: 纵坐标2
def getPercentParams(y1, y2)
	y0 = 0
	y25 = 0
	y50 = 0
	y75 = 0
	y100 = 0
	y0 = y1
	if y1 <= y2
		y25 = y1 + (y2 - y1) / 4.0
		y50 = y1 + (y2 - y1) / 2.0
		y75 = y1 + (y2 - y1) * 3.0 / 4.0
	else
		y25 = y2 + (y1 - y2) * 3.0 / 4.0
		y50 = y2 + (y1 - y2) / 2.0
		y75 = y2 + (y1 - y2) / 4.0
	end
	y100 = y2
	list = []
	list.push(y0)
	list.push(y25)
	list.push(y50)
	list.push(y75)
	list.push(y100)
	return list
end

#根据坐标计算矩形
#x1:横坐标1
#y1:纵坐标1
#x2:横坐标2
#y2:纵坐标2
def rectangleXYWH(chart, x1, y1, x2, y2)
	chart.xChart = x2
	if x1 < x2
		chart.xChart = x1
	end
	chart.yChart = y2
	if y1 < y2
		chart.yChart = y1
	end
	chart.wChart = (x1 - x2).abs
	chart.hChart = (y1 - y2).abs
	if chart.wChart <= 0
		chart.wChart = 4
	end
	if chart.hChart <= 0
		chart.hChart = 4
	end
end

#根据位置计算索引
#chart:图表
#mp:坐标
def getChartIndex(chart, mp)
	if chart.data != nil && chart.data.length == 0
		return -1
	end
	if mp.x <= 0
		return 0
	end
	intX = (mp.x - chart.leftVScaleWidth - chart.hScalePixel).to_i
	index = (chart.firstVisibleIndex + intX / chart.hScalePixel).to_i
	if intX % chart.hScalePixel != 0
		index = index + 1
	end
	if index < 0
		index = 0
	elsif chart.data && index > chart.data.length - 1
		index = chart.data.length - 1
	end
	return index
end

#获取最大显示记录条数
#chart:图表
#hScalePixel:间隔
#pureH:横向距离
def getChartMaxVisibleCount(chart, hScalePixel, pureH)
	count = ((pureH - hScalePixel) / hScalePixel).to_i
    if count < 0
        count = 0
	end
    return count
end

#获取图表层的高度
#chart:图表
def getCandleDivHeight(chart)
	height = chart.size.cy - chart.hScaleHeight
	if height > 0
		return height * chart.candleDivPercent
	else
		return 0
	end
end

#获取成交量层的高度
#chart:图表
def getVolDivHeight(chart)
	height = chart.size.cy - chart.hScaleHeight
	if height > 0
		return height * chart.volDivPercent
	else
		return 0
	end
end

#获取指标层的高度
#chart:图表
def getIndDivHeight(chart)
	height = chart.size.cy - chart.hScaleHeight
	if height > 0
		return height * chart.indDivPercent
	else
		return 0
	end
end

#获取指标层2的高度
#chart:图表
def getIndDivHeight2(chart)
	height = chart.size.cy - chart.hScaleHeight
	if height > 0
		return height * chart.indDivPercent2
	else
		return 0
	end
end

#获取横向工作区
#chart:图表
def getChartWorkAreaWidth(chart)
	return chart.size.cx - chart.leftVScaleWidth - chart.rightVScaleWidth - chart.rightSpace
end

#根据索引获取横坐标
#chart:图表
#index:索引
def getChartX(chart, index)
	return chart.leftVScaleWidth + (index - chart.firstVisibleIndex) * chart.hScalePixel + chart.hScalePixel
end

#根据日期获取索引
#chart:图表
#date:日期
def getChartIndexByDate(chart, date)
	index = -1
	for i in 0..chart.data.length - 1
		if chart.data[i].date == date
			index = i
			break
		end
	end
	return index
end

#根据索引获取日期
#chart:图表
#index:索引
def getChartDateByIndex(chart, index)
	date = ""
    if index >= 0 && index < chart.data.length
        date = chart.data[index].date
	end
    return date
end

#检查最后可见索引
#chart:图表
def checkChartLastVisibleIndex(chart)
	if chart.lastVisibleIndex > chart.data.length - 1
        chart.lastVisibleIndex = chart.data.length - 1
	end
    if chart.data.length > 0 && chart.lastVisibleIndex != -1
        chart.lastVisibleKey = chart.data[chart.lastVisibleIndex].date
        if chart.lastVisibleIndex == chart.data.length - 1
            chart.lastRecordIsVisible = true
        else
            chart.lastRecordIsVisible = false
		end
    else
        chart.lastVisibleKey = 0
        chart.lastRecordIsVisible = true
	end
end

#自动设置首先可见和最后可见的记录号
#chart:图表
def resetChartVisibleRecord(chart)
	rowsCount = chart.data.length
    workingAreaWidth = getChartWorkAreaWidth(chart)
    if chart.autoFillHScale
        if workingAreaWidth > 0 && rowsCount > 0
            chart.hScalePixel = workingAreaWidth / rowsCount
            chart.firstVisibleIndex = 0
            chart.lastVisibleIndex = rowsCount - 1
		end
    else
        maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, workingAreaWidth)
        if rowsCount == 0
            chart.firstVisibleIndex = -1
            chart.lastVisibleIndex = -1
        else
            if rowsCount < maxVisibleRecord
                chart.lastVisibleIndex = rowsCount - 1
                chart.firstVisibleIndex = 0
            else
                if chart.firstVisibleIndex != -1 && chart.lastVisibleIndex != -1 && chart.lastRecordIsVisible == false
                    index = getChartIndexByDate(chart, chart.lastVisibleKey)
                    if index != -1
                        chart.lastVisibleIndex = index
					end
                    chart.firstVisibleIndex = chart.lastVisibleIndex - maxVisibleRecord + 1
                    if chart.firstVisibleIndex < 0
                        chart.firstVisibleIndex = 0
                        chart.lastVisibleIndex = chart.firstVisibleIndex + maxVisibleRecord
                        checkChartLastVisibleIndex(chart)
					end
                else
                    chart.lastVisibleIndex = rowsCount - 1
                    chart.firstVisibleIndex = chart.lastVisibleIndex - maxVisibleRecord + 1
                    if chart.firstVisibleIndex > chart.lastVisibleIndex
                        chart.firstVisibleIndex = chart.lastVisibleIndex
					end
				end
			end
		end
	end
end

#设置可见索引
#chart:图表
#firstVisibleIndex:起始索引
#lastVisibleIndex:结束索引
def setChartVisibleIndex(chart, firstVisibleIndex, lastVisibleIndex)
	xScalePixel = getChartWorkAreaWidth(chart) / (lastVisibleIndex - firstVisibleIndex + 1)
    if xScalePixel < 1000000
        chart.firstVisibleIndex = firstVisibleIndex
        chart.lastVisibleIndex = lastVisibleIndex
        if lastVisibleIndex != chart.data.length - 1
            chart.lastRecordIsVisible = false
        else
            chart.lastRecordIsVisible = true
		end
        chart.hScalePixel = xScalePixel
        checkChartLastVisibleIndex(chart)
	end
end

#计算数值在层中的位置
#chart:图表
#divIndex:所在层
#chart:数值
def getChartY(chart, divIndex, value)
	if divIndex == 0
		if chart.candleMax > chart.candleMin
			cValue = value
			cMax = chart.candleMax
			cMin = chart.candleMin
			if chart.vScaleType != "standard"
				if cValue > 0
					cValue = Math.log10(cValue)
				elsif cValue < 0
					cValue = -Math.log10(cValue.abs)
				end
				if cMax > 0
					cMax = Math.log10(cMax)
				elsif cMax < 0
					cMax = -Math.log10(cMax.abs)
				end
				if cMin > 0
					cMin = Math.log10(cMin)
				elsif cMin < 0
					cMin = -Math.log10(cMin.abs)
				end
			end
			rate = (cValue - cMin) / (cMax - cMin)
			divHeight = getCandleDivHeight(chart)
			return divHeight - chart.candlePaddingBottom - (divHeight - chart.candlePaddingTop - chart.candlePaddingBottom) * rate
		else
			return 0
		end
	elsif divIndex == 1
		if chart.volMax > chart.volMin
			rate = (value - chart.volMin) / (chart.volMax - chart.volMin)
			candleHeight = getCandleDivHeight(chart)
			volHeight = getVolDivHeight(chart)
			return candleHeight + volHeight - chart.volPaddingBottom - (volHeight - chart.volPaddingTop - chart.volPaddingBottom) * rate
		else
			return 0
		end
	elsif divIndex == 2
		if chart.indMax > chart.indMin
			rate = (value - chart.indMin) / (chart.indMax - chart.indMin)
			candleHeight = getCandleDivHeight(chart)
			volHeight = getVolDivHeight(chart)
			indHeight = getIndDivHeight(chart)
			return candleHeight + volHeight + indHeight - chart.indPaddingBottom - (indHeight - chart.indPaddingTop - chart.indPaddingBottom) * rate
		else
			return 0
		end
	elsif divIndex == 3
		if chart.indMax2 > chart.indMin2
			rate = (value - chart.indMin2) / (chart.indMax2 - chart.indMin2)
			candleHeight = getCandleDivHeight(chart)
			volHeight = getVolDivHeight(chart)
			indHeight = getIndDivHeight(chart)
			indHeight2 = getIndDivHeight2(chart)
			return candleHeight + volHeight + indHeight + indHeight2- chart.indPaddingBottom2 - (indHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) * rate
		else
			return 0
		end
	end
	return 0
end

#计算数值在层中右轴的位置
#chart:图表
#divIndex:所在层
#chart:数值
def getChartYInRight(chart, divIndex, value)
	if divIndex == 0
		if chart.candleMaxRight > chart.candleMinRight
			cValue = value
			cMax = chart.candleMaxRight
			cMin = chart.candleMinRight
			if chart.vScaleType != "standard"
				if cValue > 0
					cValue = Math.log10(cValue)
				elsif cValue < 0
					cValue = -Math.log10(cValue.abs)
				end
				if cMax > 0
					cMax = Math.log10(cMax)
				elsif cMax < 0
					cMax = -Math.log10(cMax.abs)
				end
				if cMin > 0
					cMin = Math.log10(cMin)
				elsif cMin < 0
					cMin = -Math.log10(cMin.abs)
				end
			end
			rate = (cValue - cMin) / (cMax - cMin)
			divHeight = getCandleDivHeight(chart)
			return divHeight - chart.candlePaddingBottom - (divHeight - chart.candlePaddingTop - chart.candlePaddingBottom) * rate
		else
			return 0
		end
	elsif divIndex == 1
		if chart.volMaxRight > chart.volMinRight
			rate = (value - chart.volMinRight) / (chart.volMaxRight - chart.volMinRight)
			candleHeight = getCandleDivHeight(chart)
			volHeight = getVolDivHeight(chart)
			return candleHeight + volHeight - chart.volPaddingBottom - (volHeight - chart.volPaddingTop - chart.volPaddingBottom) * rate
		else
			return 0
		end
	elsif divIndex == 2
		if chart.indMaxRight > chart.indMinRight
			rate = (value - chart.indMinRight) / (chart.indMaxRight - chart.indMinRight)
			candleHeight = getCandleDivHeight(chart)
			volHeight = getVolDivHeight(chart)
			indHeight = getIndDivHeight(chart)
			return candleHeight + volHeight + indHeight - chart.indPaddingBottom - (indHeight - chart.indPaddingTop - chart.indPaddingBottom) * rate
		else
			return 0
		end
	elsif divIndex == 3
		if chart.indMax2Right > chart.indMin2Right
			rate = (value - chart.indMin2Right) / (chart.indMax2Right - chart.indMin2Right)
			candleHeight = getCandleDivHeight(chart)
			volHeight = getVolDivHeight(chart)
			indHeight = getIndDivHeight(chart)
			indHeight2 = getIndDivHeight2(chart)
			return candleHeight + volHeight + indHeight + indHeight2- chart.indPaddingBottom2 - (indHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) * rate
		else
			return 0
		end
	end
	return 0
end

#根据坐标获取对应的值
#chart:图表
#point:坐标
def getChartValue(chart, point)
	candleHeight = getCandleDivHeight(chart)
	volHeight = getVolDivHeight(chart)
	indHeight = getIndDivHeight(chart)
	indHeight2 = getIndDivHeight2(chart)
	if point.y <= candleHeight
		rate = (candleHeight - chart.candlePaddingBottom - point.y) / (candleHeight - chart.candlePaddingTop - chart.candlePaddingBottom)
		cMin = chart.candleMin
		cMax = chart.candleMax
		if chart.vScaleType != "standard"
			if cMax > 0
				cMax = Math.log10(cMax)
			elsif cMax < 0
				cMax = - Math.log10(cMax.abs)
			end
			if cMin > 0
				cMin =  Math.log10(cMin)
			elsif cMin < 0
				cMin = - Math.log10(cMin.abs)
			end
		end
		result = cMin + (cMax - cMin) * rate
		if chart.vScaleType != "standard"
			return 10 ** result
		else
			return result
		end
	elsif point.y > candleHeight and point.y <= candleHeight + volHeight
		rate = (volHeight - chart.volPaddingBottom - (point.y - candleHeight)) / (volHeight - chart.volPaddingTop - chart.volPaddingBottom)
		return chart.volMin + (chart.volMax - chart.volMin) * rate
	elsif point.y > candleHeight + volHeight and point.y <= candleHeight + volHeight + indHeight
		rate = (indHeight - chart.indPaddingBottom - (point.y - candleHeight - volHeight)) / (indHeight - chart.indPaddingTop - chart.indPaddingBottom)
		return chart.indMin + (chart.indMax - chart.indMin) * rate
	elsif point.y > candleHeight + volHeight + indHeight and point.y <= candleHeight + volHeight + indHeight + indHeight2
		rate = (indHeight2 - chart.indPaddingBottom2 - (point.y - candleHeight - volHeight - indHeight)) / (indHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2)
		return chart.indMin2 + (chart.indMax2 - chart.indMin2) * rate
	end
	return 0
end

#根据坐标获取图表层对应的值
#chart:图表
#point:坐标
def getCandleDivValue(chart, point)
	candleHeight = getCandleDivHeight(chart)
	rate = (candleHeight - chart.candlePaddingBottom - point.y) / (candleHeight - chart.candlePaddingTop - chart.candlePaddingBottom)
	cMin = chart.candleMin
	cMax = chart.candleMax
	if chart.vScaleType != "standard"
		if cMax > 0
			cMax = Math.log10(cMax)
		elsif cMax < 0
			cMax = -Math.log10(cMax.abs)
		end
		if cMin > 0
			cMin = Math.log10(cMin)
		elsif cMin < 0
			cMin = -Math.log10(cMin.abs)
		end
	end
	result = cMin + (cMax - cMin) * rate
	if chart.vScaleType != "standard"
		return 10 ** result
	else
		return result
	end
end

#清除缓存数据方法
#chart:图表
def clearDataArr(chart)
	chart.closearr = []
	chart.allema12 = []
	chart.allema26 = []
	chart.alldifarr = []
	chart.alldeaarr = []
	chart.allmacdarr = []
	chart.boll_mid = []
	chart.boll_up = []
	chart.boll_down = []
	chart.bias1 = []
	chart.bias2 = []
	chart.bias3 = []
	chart.dma1 = []
	chart.dma2 = []
	chart.kdj_k = []
	chart.kdj_d = []
	chart.kdj_j = []
	chart.bbi = []
	chart.roc = []
	chart.roc_ma = []
	chart.rsi1 = []
	chart.rsi2 = []
	chart.rsi3 = []
	chart.wr1 = []
	chart.wr2 = []
	chart.trix = []
	chart.trix_ma = []
	chart.cci = []
end

#获取数据
#chart:图表
def calcChartIndicator(chart)
	clearDataArr(chart)
	closeArr = []
	highArr = []
	lowArr = []
	if chart.data != nil && chart.data.length > 0
		for i in 0..chart.data.length - 1
			chart.closearr.push(chart.data[i].close)
			closeArr.push(chart.data[i].close)
			highArr.push(chart.data[i].high)
			lowArr.push(chart.data[i].low)
		end
	end
	if chart.mainIndicator == "MA"
		chart.ma5 = MA(closeArr, 5)
		chart.ma10 = MA(closeArr, 10)
		chart.ma20 = MA(closeArr, 20)
		chart.ma30 = MA(closeArr, 30)
		chart.ma120 = MA(closeArr, 120)
		chart.ma250 = MA(closeArr, 250)
	elsif chart.mainIndicator == "BOLL"
		getBollData(closeArr, 20, chart.boll_up, chart.boll_mid, chart.boll_down)
	end
	if chart.showIndicator == "MACD"
		chart.allema12.push(chart.closearr[0])
		chart.allema26.push(chart.closearr[0])
		chart.alldeaarr.push(0)
		for i in 1..chart.closearr.length - 1
			chart.allema12.push(getEMA(12, chart.closearr[i], chart.allema12[i - 1]))
			chart.allema26.push(getEMA(26, chart.closearr[i], chart.allema26[i - 1]))
		end
		chart.alldifarr = getDIF(chart.allema12, chart.allema26)
		for i in 1..chart.alldifarr.length - 1
			chart.alldeaarr.push(chart.alldeaarr[i - 1] * 8 / 10 + chart.alldifarr[i] * 2 / 10)
		end
		chart.allmacdarr = getMACD(chart.alldifarr, chart.alldeaarr)
	elsif chart.showIndicator == "BIAS"
		getBIASData(chart.closearr, 6, 12, 24, chart.bias1, chart.bias2, chart.bias3)
	elsif chart.showIndicator == "TRIX"
		getTRIXData(chart.closearr, 10, 50, chart.trix, chart.trix_ma)
	elsif chart.showIndicator == "CCI"
		getCCIData(closeArr, highArr, lowArr, 14, chart.cci)
	elsif chart.showIndicator == "BBI"
		getBBIData(closeArr, 3, 6, 12, 24, chart.bbi)
	elsif chart.showIndicator == "ROC"
		getRocData(closeArr, 12, 6, chart.roc, chart.roc_ma)
	elsif chart.showIndicator == "WR"
		getWRData(closeArr, highArr, lowArr, 5, 10, chart.wr1, chart.wr2)
	elsif chart.showIndicator == "DMA"
		getDMAData(closeArr, 10, 50, chart.dma1, chart.dma2)
	elsif chart.showIndicator == "RSI"
		getRSIData(closeArr, 6, 12, 24, chart.rsi1, chart.rsi2, chart.rsi3)
	elsif chart.showIndicator == "KDJ"
		getKDJData(chart, highArr, lowArr, closeArr, 9, 3, 3, chart.kdj_k, chart.kdj_d, chart.kdj_j)
	end
	if chart.paint.onCalculateChartMaxMin != nil
		chart.paint.onCalculateChartMaxMin.call(chart)
	else
		calculateChartMaxMin(chart)
	end
end

#计算最大最小值
#chart:图表
def calculateChartMaxMin(chart)
	chart.candleMax = 0
	chart.candleMin = 0
	chart.volMax = 0
	chart.volMin = 0
	chart.indMin = 0
	chart.indMin = 0
	isTrend = false
	if chart.cycle == "trend"
		isTrend = true
	end
	firstOpen = 0
	load1 = false
	load2 = false
	load3 = false
	load4 = false
	if chart.data != nil && chart.data.length > 0
		lastValidIndex = chart.lastVisibleIndex
		if chart.lastValidIndex != -1
			lastValidIndex = chart.lastValidIndex
		end
		for i in chart.firstVisibleIndex..lastValidIndex
			if i == chart.firstVisibleIndex
				if isTrend
					chart.candleMax = chart.data[i].close
					chart.candleMin = chart.data[i].close
					firstOpen = chart.data[i].close
				else
					chart.candleMax = chart.data[i].high
					chart.candleMin = chart.data[i].low
				end
				load1 = true
				load2 = true
				chart.volMax = chart.data[i].volume
				if chart.showIndicator == "MACD"
					chart.indMax = chart.alldifarr[i]
					chart.indMin = chart.alldifarr[i]
					load3 = true
				elsif chart.showIndicator == "KDJ"
					chart.indMax = chart.kdj_k[i]
					chart.indMin = chart.kdj_k[i]
					load3 = true
				elsif chart.showIndicator == "RSI"
					chart.indMax = chart.rsi1[i]
					chart.indMin = chart.rsi1[i]
					load3 = true
				elsif chart.showIndicator == "BIAS"
					chart.indMax = chart.bias1[i]
					chart.indMin = chart.bias1[i]
					load3 = true
				elsif chart.showIndicator == "ROC"
					chart.indMax = chart.roc[i]
					chart.indMin = chart.roc[i]
					load3 = true
				elsif chart.showIndicator == "WR"
					chart.indMax = chart.wr1[i]
					chart.indMin = chart.wr1[i]
					load3 = true
				elsif chart.showIndicator == "CCI"
					chart.indMax = chart.cci[i]
					chart.indMin = chart.cci[i]
					load3 = true
				elsif chart.showIndicator == "BBI"
					chart.indMax = chart.bbi[i]
					chart.indMin = chart.bbi[i]
					load3 = true
				elsif chart.showIndicator == "TRIX"
					chart.indMax = chart.trix[i]
					chart.indMin = chart.trix[i]
					load3 = true
				elsif chart.showIndicator == "DMA"
					chart.indMax = chart.dma1[i]
					chart.indMin = chart.dma1[i]
					load3 = true
				end
			else
				if isTrend
					if chart.candleMax < chart.data[i].close
						chart.candleMax = chart.data[i].close
					end
					if chart.candleMin > chart.data[i].close
						chart.candleMin = chart.data[i].close
					end
				else
					if chart.candleMax < chart.data[i].high
						chart.candleMax = chart.data[i].high
					end
					if chart.candleMin > chart.data[i].low
						chart.candleMin = chart.data[i].low
					end
				end
				if chart.volMax < chart.data[i].volume
					chart.volMax = chart.data[i].volume
				end
				if chart.showIndicator == "MACD"
					if chart.indMax < chart.alldifarr[i]
						chart.indMax = chart.alldifarr[i]
					end
					if chart.indMax < chart.alldeaarr[i]
						chart.indMax = chart.alldeaarr[i]
					end
					if chart.indMax < chart.allmacdarr[i]
						chart.indMax = chart.allmacdarr[i]
					end
					if chart.indMin > chart.alldifarr[i]
						chart.indMin = chart.alldifarr[i]
					end
					if chart.indMin > chart.alldeaarr[i]
						chart.indMin = chart.alldeaarr[i]
					end
					if chart.indMin > chart.allmacdarr[i]
						chart.indMin = chart.allmacdarr[i]
					end
				elsif chart.showIndicator == "KDJ"
					if chart.indMax < chart.kdj_k[i]
						chart.indMax = chart.kdj_k[i]
					end
					if chart.indMax < chart.kdj_d[i]
						chart.indMax = chart.kdj_d[i]
					end
					if chart.indMax < chart.kdj_j[i]
						chart.indMax = chart.kdj_j[i]
					end
					if chart.indMin > chart.kdj_k[i]
						chart.indMin = chart.kdj_k[i]
					end
					if chart.indMin > chart.kdj_d[i]
						chart.indMin = chart.kdj_d[i]
					end
					if chart.indMin > chart.kdj_j[i]
						chart.indMin = chart.kdj_j[i]
					end
				elsif chart.showIndicator == "RSI"
					if chart.indMax < chart.rsi1[i]
						chart.indMax = chart.rsi1[i]
					end
					if chart.indMax < chart.rsi2[i]
						chart.indMax = chart.rsi2[i]
					end
					if chart.indMax < chart.rsi3[i]
						chart.indMax = chart.rsi3[i]
					end
					if chart.indMin > chart.rsi1[i]
						chart.indMin = chart.rsi1[i]
					end
					if chart.indMin > chart.rsi2[i]
						chart.indMin = chart.rsi2[i]
					end
					if chart.indMin > chart.rsi3[i]
						chart.indMin = chart.rsi3[i]
					end
				elsif chart.showIndicator == "BIAS"
					if chart.indMax < chart.bias1[i]
						chart.indMax = chart.bias1[i]
					end
					if chart.indMax < chart.bias2[i]
						chart.indMax = chart.bias2[i]
					end
					if chart.indMax < chart.bias3[i]
						chart.indMax = chart.bias3[i]
					end
					if chart.indMin > chart.bias1[i]
						chart.indMin = chart.bias1[i]
					end
					if chart.indMin > chart.bias2[i]
						chart.indMin = chart.bias2[i]
					end
					if chart.indMin > chart.bias3[i]
						chart.indMin = chart.bias3[i]
					end
				elsif chart.showIndicator == "ROC"
					if chart.indMax < chart.roc[i]
						chart.indMax = chart.roc[i]
					end
					if chart.indMax < chart.roc_ma[i]
						chart.indMax = chart.roc_ma[i]
					end
					if chart.indMin > chart.roc[i]
						chart.indMin = chart.roc[i]
					end
					if chart.indMin > chart.roc_ma[i]
						chart.indMin = chart.roc_ma[i]
					end
				elsif chart.showIndicator == "WR"
					if chart.indMax < chart.wr1[i]
						chart.indMax = chart.wr1[i]
					end
					if chart.indMax < chart.wr2[i]
						chart.indMax = chart.wr2[i]
					end
					if chart.indMin > chart.wr1[i]
						chart.indMin = chart.wr1[i]
					end
					if chart.indMin > chart.wr2[i]
						chart.indMin = chart.wr2[i]
					end
				elsif chart.showIndicator == "CCI"
					if chart.indMax < chart.cci[i]
						chart.indMax = chart.cci[i]
					end
					if chart.indMin > chart.cci[i]
						chart.indMin = chart.cci[i]
					end
				elsif chart.showIndicator == "BBI"
					if chart.indMax < chart.bbi[i]
						chart.indMax = chart.bbi[i]
					end
					if chart.indMin > chart.bbi[i]
						chart.indMin = chart.bbi[i]
					end
				elsif chart.showIndicator == "TRIX"
					if chart.indMax < chart.trix[i]
						chart.indMax = chart.trix[i]
					end
					if chart.indMax < chart.trix_ma[i]
						chart.indMax = chart.trix_ma[i]
					end
					if chart.indMin > chart.trix[i]
						chart.indMin = chart.trix[i]
					end
					if chart.indMin > chart.trix_ma[i]
						chart.indMin = chart.trix_ma[i]
					end
				elsif chart.showIndicator == "DMA"
					if chart.indMax < chart.dma1[i]
						chart.indMax = chart.dma1[i]
					end
					if chart.indMax < chart.dma2[i]
						chart.indMax = chart.dma2[i]
					end
					if chart.indMin > chart.dma1[i]
						chart.indMin = chart.dma1[i]
					end
					if chart.indMin > chart.dma2[i]
						chart.indMin = chart.dma2[i]
					end
				end
			end
		end
	end
	if chart.shapes.length > 0
		lastValidIndex = chart.lastVisibleIndex
		if chart.lastValidIndex != -1
			lastValidIndex = chart.lastValidIndex
		end
		for s in 0..chart.shapes.length - 1
			shape = chart.shapes[s]
			if shape.datas.length > 0
				for i in chart.firstVisibleIndex..lastValidIndex
					if shape.divIndex == 0
						if load1 == false && i == chart.firstVisibleIndex
							if shape.leftOrRight
								chart.candleMax = shape.datas[i]
								chart.candleMin = shape.datas[i]
							else
								chart.candleMaxRight = shape.datas[i]
								chart.candleMinRight = shape.datas[i]
							end
							load1 = true
						else
							if shape.leftOrRight
								if shape.datas[i] > chart.candleMax
									chart.candleMax = shape.datas[i]
								end
								if shape.datas[i] < chart.candleMin
									chart.candleMin = shape.datas[i]
								end
							else
								if shape.datas[i] > chart.candleMaxRight
									chart.candleMaxRight = shape.datas[i]
								end
								if shape.datas[i] < chart.candleMinRight
									chart.candleMinRight = shape.datas[i]
								end
							end
						end
					elsif shape.divIndex == 1
						if load2 == false && i == chart.firstVisibleIndex
							if shape.leftOrRight
								chart.volMax = shape.datas[i]
								chart.volMin = shape.datas[i]
							else
								chart.volMaxRight = shape.datas[i]
								chart.volMinRight = shape.datas[i]
							end
							load2 = true
						else
							if shape.leftOrRight
								if shape.datas[i] > chart.volMax
									chart.volMax = shape.datas[i]
								end
								if shape.datas[i] < chart.volMin
									chart.volMin = shape.datas[i]
								end
							else
								if shape.datas[i] > chart.volMaxRight
									chart.volMaxRight = shape.datas[i]
								end
								if shape.datas[i] < chart.volMinRight
									chart.volMinRight = shape.datas[i]
								end
							end
						end
					elsif shape.divIndex == 2
						if load3 == false && i == chart.firstVisibleIndex
							if shape.leftOrRight
								chart.indMax = shape.datas[i]
								chart.indMin = shape.datas[i]
							else
								chart.indMaxRight = shape.datas[i]
								chart.indMinRight = shape.datas[i]
							end
							load3 = true
						else
							if shape.leftOrRight
								if shape.datas[i] > chart.indMax
									chart.indMax = shape.datas[i]
								end
								if shape.datas[i] < chart.indMin
									chart.indMin = shape.datas[i]
								end
							else
								if shape.datas[i] > chart.indMaxRight
									chart.indMaxRight = shape.datas[i]
								end
								if shape.datas[i] < chart.indMinRight
									chart.indMinRight = shape.datas[i]
								end
							end
						end
					elsif shape.divIndex == 3
						if load4 == false && i == chart.firstVisibleIndex
							if shape.leftOrRight
								chart.indMax2 = shape.datas[i]
								chart.indMin2 = shape.datas[i]
							else
								chart.indMax2Right = shape.datas[i]
								chart.indMin2Right = shape.datas[i]
							end
							load4 = true
						else
							if shape.leftOrRight
								if shape.datas[i] > chart.indMax2
									chart.indMax2 = shape.datas[i]
								end
								if shape.datas[i] < chart.indMin2
									chart.indMin2 = shape.datas[i]
								end
							else
								if shape.datas[i] > chart.indMax2Right
									chart.indMax2Right = shape.datas[i]
								end
								if shape.datas[i] < chart.indMin2Right
									chart.indMin2Right = shape.datas[i]
								end
							end
						end
					end
				end
			end
			if shape.datas2.length > 0
				for i in chart.firstVisibleIndex..lastValidIndex
					if shape.divIndex == 0
						if shape.leftOrRight
							if shape.datas2[i] > chart.candleMax
								chart.candleMax = shape.datas2[i]
							end
							if shape.datas2[i] < chart.candleMin
								chart.candleMin = shape.datas2[i]
							end
						else
							if shape.datas2[i] > chart.candleMaxRight
								chart.candleMaxRight = shape.datas2[i]
							end
							if shape.datas2[i] < chart.candleMinRight
								chart.candleMinRight = shape.datas2[i]
							end
						end
					elsif shape.divIndex == 1
						if shape.leftOrRight
							if shape.datas2[i] > chart.volMax
								chart.volMax = shape.datas2[i]
							end
							if shape.datas2[i] < chart.volMin
								chart.volMin = shape.datas2[i]
							end
						else
							if shape.datas2[i] > chart.volMaxRight
								chart.volMaxRight = shape.datas2[i]
							end
							if shape.datas2[i] < chart.volMinRight
								chart.volMinRight = shape.datas2[i]
							end
						end
					elsif shape.divIndex == 2
						if shape.leftOrRight
							if shape.datas2[i] > chart.indMax
								chart.indMax = shape.datas2[i]
							end
							if shape.datas2[i] < chart.indMin
								chart.indMin = shape.datas2[i]
							end
						else
							if shape.datas2[i] > chart.indMaxRight
								chart.indMaxRight = shape.datas2[i]
							end
							if shape.datas2[i] < chart.indMinRight
								chart.indMinRight = shape.datas2[i]
							end
						end
					elsif shape.divIndex == 3
						if shape.leftOrRight
							if shape.datas2[i] > chart.indMax2
								chart.indMax2 = shape.datas2[i]
							end
							if shape.datas2[i] < chart.indMin2
								chart.indMin2 = shape.datas2[i]
							end
						else
							if shape.datas2[i] > chart.indMax2Right
								chart.indMax2Right = shape.datas2[i]
							end
							if shape.datas2[i] < chart.indMin2Right
								chart.indMin2Right = shape.datas2[i]
							end
						end
					end
				end
			end
		end
	end			
	if isTrend
		subMax = [(chart.candleMax - firstOpen).abs, (chart.candleMin - firstOpen).abs].max
		chart.candleMax = firstOpen + subMax
		chart.candleMin = firstOpen - subMax
	else
		if chart.candleMax == 0 && chart.candleMin == 0
			chart.candleMax = 1
			chart.candleMin = -1
		end
		if chart.volMax == 0 && chart.volMin == 0
			chart.volMax = 1
			chart.volMin = -1
		end
		if chart.indMax == 0 && chart.indMin == 0
			chart.indMax = 1
			chart.indMin = -1
		end
		if chart.indMax2 == 0 && chart.indMin2 == 0
			chart.indMax2 = 1
			chart.indMin2 = -1
		end
		if chart.candleMaxRight == 0 && chart.candleMinRight == 0
			chart.candleMaxRight = 1
			chart.candleMinRight = -1
		end
		if chart.volMaxRight == 0 && chart.volMinRight == 0
			chart.volMaxRight = 1
			chart.volMinRight = -1
		end
		if chart.indMaxRight == 0 && chart.indMinRight == 0
			chart.indMaxRight = 1
			chart.indMinRight = -1
		end
		if chart.indMax2Right == 0 && chart.indMin2Right == 0
			chart.indMax2Right = 1
			chart.indMin2Right = -1
		end
	end
end

#缩小
#chart:图表
def zoomOutChart(chart)
	if chart.autoFillHScale == false
		hScalePixel = chart.hScalePixel
		oldX = getChartX(chart, chart.crossStopIndex)
		pureH = getChartWorkAreaWidth(chart)
		oriMax = -1
		maxValue = -1
		deal = 0
		dataCount = chart.data.length
		findex = chart.firstVisibleIndex
		lindex = chart.lastVisibleIndex
		if hScalePixel < pureH
			oriMax = getChartMaxVisibleCount(chart, hScalePixel, pureH)
			if dataCount < oriMax
				deal = 1
			end
			if hScalePixel > 3
				hScalePixel += 1
			else
				if hScalePixel == 1
					hScalePixel = 2
				else
					hScalePixel = hScalePixel * 1.5
					if hScalePixel > 3
						hScalePixel = hScalePixel.to_i
					end
				end
			end
			maxValue = getChartMaxVisibleCount(chart, hScalePixel, pureH)
			if dataCount >= maxValue
				if deal == 1
					lindex = dataCount - 1
				end
				findex = lindex - maxValue + 1
				if findex < 0
					findex = 0
				end
			end
		end
		chart.hScalePixel = hScalePixel
		chart.firstVisibleIndex = findex
		chart.lastVisibleIndex = lindex
		if chart.showCrossLine
			newX = getChartX(chart, chart.crossStopIndex)
			if newX > oldX
				while chart.lastVisibleIndex < chart.data.length - 1
					chart.firstVisibleIndex = chart.firstVisibleIndex + 1
					chart.lastVisibleIndex = chart.lastVisibleIndex + 1
					newX = getChartX(chart, chart.crossStopIndex)
					if newX <= oldX
						break
					end
				end
			elsif newX < oldX
				while chart.firstVisibleIndex > 0
					chart.firstVisibleIndex = chart.firstVisibleIndex - 1
					chart.lastVisibleIndex = chart.lastVisibleIndex - 1
					newX = getChartX(chart, chart.crossStopIndex)
					if newX >= oldX
						break
					end
				end
			end
		end
		checkChartLastVisibleIndex(chart)
		if chart.paint.onCalculateChartMaxMin != nil
			chart.paint.onCalculateChartMaxMin.call(chart)
		else
			calculateChartMaxMin(chart)
		end
	end
end

#放大
#chart:图表
def zoomInChart(chart)
	if chart.autoFillHScale == false
		hScalePixel = chart.hScalePixel
		oldX = getChartX(chart, chart.crossStopIndex)
		pureH = getChartWorkAreaWidth(chart)
		maxValue = -1
		dataCount = chart.data.length
		findex = chart.firstVisibleIndex
		lindex = chart.lastVisibleIndex
		if hScalePixel > 3
			hScalePixel -= 1
		else
			hScalePixel = hScalePixel * 2 / 3
			if hScalePixel > 3
				hScalePixel = hScalePixel.to_i
			end
		end
		maxValue = getChartMaxVisibleCount(chart, hScalePixel, pureH)
		if maxValue >= dataCount
			if hScalePixel < 1
				hScalePixel = pureH / maxValue
			end
			findex = 0
			lindex = dataCount - 1
		else
			findex = lindex - maxValue + 1
			if findex < 0
				findex = 0
			end
		end
		chart.hScalePixel = hScalePixel
		chart.firstVisibleIndex = findex
		chart.lastVisibleIndex = lindex
		if chart.showCrossLine
			newX = getChartX(chart, chart.crossStopIndex)
			if newX > oldX
				while chart.lastVisibleIndex < chart.data.length - 1
					chart.firstVisibleIndex = chart.firstVisibleIndex + 1
					chart.lastVisibleIndex = chart.lastVisibleIndex + 1
					newX = getChartX(chart, chart.crossStopIndex)
					if newX <= oldX
						break
					end
				end
			elsif newX < oldX
				while chart.firstVisibleIndex > 0
					chart.firstVisibleIndex = chart.firstVisibleIndex - 1
					chart.lastVisibleIndex = chart.lastVisibleIndex - 1
					newX = getChartX(chart, chart.crossStopIndex)
					if newX >= oldX
						break
					end
				end
			end
		end
		checkChartLastVisibleIndex(chart)
		if chart.paint.onCalculateChartMaxMin != nil
			chart.paint.onCalculateChartMaxMin.call(chart)
		else
			calculateChartMaxMin(chart)
		end
	end
end

#计算坐标轴
#min:最小值
#max:最大值
#yLen:长度
#maxSpan:最大间隔
#minSpan:最小间隔
#defCount:数量
def chartGridScale(chart, minValue, maxValue, yLen, maxSpan, minSpan, defCount)
	if defCount > 0 && maxSpan > 0 && minSpan > 0
		subValue = maxValue - minValue
		nMinCount = (yLen / maxSpan).ceil.to_i
		nMaxCount = (yLen / minSpan).floor.to_i
		nCount = defCount
		logStep = subValue / nCount
		start = false
		divisor = 0
		i = 15
		nTemp = 0
		chart.gridStep = 0
		chart.gridDigit = 0
		nCount = [nMinCount, nCount].max
		nCount = [nMaxCount, nCount].min
		nCount = [nCount, 1].max
		while i >= -6
			divisor = 10.0 ** i
			if divisor < 1
				chart.gridDigit = chart.gridDigit + 1
			end
			nTemp = (logStep / divisor).floor.to_i
			if start
				if nTemp < 4
					if chart.gridDigit > 0
						chart.gridDigit = chart.gridDigit - 1
					end
				elsif nTemp >= 4 && nTemp <= 6
					nTemp = 5
					chart.gridStep = chart.gridStep + nTemp * divisor
				else
					chart.gridStep = chart.gridStep + 10 * divisor
					if chart.gridDigit > 0
						chart.gridDigit = chart.gridDigit - 1
					end
				end
				break
			elsif nTemp > 0
				chart.gridStep = nTemp * divisor + chart.gridStep
				logStep = logStep - chart.gridStep
				start = true
			end
			i = i - 1
		end
		return 1
	end
	return 0
end

#计算线性回归上下限
#chart:图表
#plot:画线
#a:直线k
#b:直线b
def getLRBandRange(chart, plot, a, b)
	bIndex = getChartIndexByDate(chart, plot.key1)
	eIndex = getChartIndexByDate(chart, plot.key2)
	tempBIndex = [bIndex, eIndex].min
	tempEIndex = [bIndex, eIndex].max
	bIndex = tempBIndex
	eIndex = tempEIndex
	upList = []
	downList = []
	for i in bIndex..eIndex
		high = chart.data[i].high
		low = chart.data[i].low
		midValue = (i - bIndex + 1) * a + b
		upList.push(high - midValue)
		downList.push(midValue - low)
	end
	chart.upSubValue = maxValue(upList)
	chart.downSubValue = maxValue(downList)
end

#获取图表的区域
#chart: 图表
#plot: 画线
def getCandleRange(chart, plot)
	bIndex = getChartIndexByDate(chart, plot.key1)
	eIndex = getChartIndexByDate(chart, plot.key2)
	tempBIndex = [bIndex, eIndex].min
	tempEIndex = [bIndex, eIndex].max
	bIndex = tempBIndex
	eIndex = tempEIndex
	highList = []
	lowList = []
	for i in bIndex..eIndex
		highList.push(chart.data[i].high)
		lowList.push(chart.data[i].low)
	end
	chart.nHighChart = maxValue(highList)
	chart.nLowChart = minValue(lowList)
end

#判断是否选中线条
#chart:图表
#mp:坐标
#divIndex:层索引
#datas:数据
#curIndex:当前索引
def selectLines(chart, mp, divIndex, datas, curIndex)
	if datas.length > 0
		topY = getChartY(chart, divIndex, datas[curIndex])
		if chart.hScalePixel <= 1
			if mp.y >= topY - 8 && mp.y <= topY + 8
				return true
			end
		else
			index = curIndex
			scaleX = getChartX(chart, index)
			judgeTop = 0
			judgeScaleX = scaleX
			if mp.x >= scaleX
				leftIndex = curIndex + 1
				if curIndex < chart.lastVisibleIndex
					rightValue = datas[leftIndex]
					judgeTop = getChartY(chart, divIndex, rightValue)
				else
					judgeTop = topY
				end
			else
				judgeScaleX = scaleX - chart.hScalePixel
				rightIndex = curIndex - 1
				if curIndex > 0
					leftValue = datas[rightIndex]
					judgeTop = getChartY(chart, divIndex, leftValue)
				else
					judgeTop = topY
				end
			end
			lineWidth = 4
			judgeX = 0
			judgeY = 0
			judgeW = 0
			judgeH = 0
			if judgeTop >= topY
				judgeX = judgeScaleX
				judgeY = topY - 2 - lineWidth
				judgeW = chart.hScalePixel
				judgeH = judgeTop - topY + 4 + lineWidth
				if judgeH < 4
					judgeH = 4
				end
			else
				judgeX = judgeScaleX
				judgeY = judgeTop - 2 - lineWidth / 2
				judgeW = chart.hScalePixel
				judgeH = topY - judgeTop + 4 + lineWidth
				if judgeH < 4
					judgeH = 4
				end
			end
			if mp.x >= judgeX && mp.x <= judgeX + judgeW && mp.y >= judgeY && mp.y <= judgeY + judgeH
				return true
			end
		end
	end
	return false
end

#判断是否在右轴选中线条
#chart:图表
#mp:坐标
#divIndex:层索引
#datas:数据
#curIndex:当前索引
def selectLinesInRight(chart, mp, divIndex, datas, curIndex)
	if datas.length > 0
		topY = getChartYInRight(chart, divIndex, datas[curIndex])
		if chart.hScalePixel <= 1
			if mp.y >= topY - 8 && mp.y <= topY + 8
				return true
			end
		else
			index = curIndex
			scaleX = getChartX(chart, index)
			judgeTop = 0
			judgeScaleX = scaleX
			if mp.x >= scaleX
				leftIndex = curIndex + 1
				if curIndex < chart.lastVisibleIndex
					rightValue = datas[leftIndex]
					judgeTop = getChartYInRight(chart, divIndex, rightValue)
				else
					judgeTop = topY
				end
			else
				judgeScaleX = scaleX - chart.hScalePixel
				rightIndex = curIndex - 1
				if curIndex > 0
					leftValue = datas[rightIndex]
					judgeTop = getChartYInRight(chart, divIndex, leftValue)
				else
					judgeTop = topY
				end
			end
			lineWidth = 4
			judgeX = 0
			judgeY = 0
			judgeW = 0
			judgeH = 0
			if judgeTop >= topY
				judgeX = judgeScaleX
				judgeY = topY - 2 - lineWidth
				judgeW = chart.hScalePixel
				judgeH = judgeTop - topY + 4 + lineWidth
				if judgeH < 4
					judgeH = 4
				end
			else
				judgeX = judgeScaleX
				judgeY = judgeTop - 2 - lineWidth / 2
				judgeW = chart.hScalePixel
				judgeH = topY - judgeTop + 4 + lineWidth
				if judgeH < 4
					judgeH = 4
				end
			end
			if mp.x >= judgeX && mp.x <= judgeX + judgeW && mp.y >= judgeY && mp.y <= judgeY + judgeH
				return true
			end
		end
	end
	return false
end

#判断是否选中图形
#chart:图表
#mp:坐标
def selectShape(chart, mp)
	if chart.data != nil && chart.data.length > 0
		chart.selectShape = ""
		chart.selectShapeEx = ""
		candleHeight = getCandleDivHeight(chart)
		volHeight = getVolDivHeight(chart)
		indHeight = getIndDivHeight(chart)
		index = getChartIndex(chart, mp)
		if mp.y >= candleHeight + volHeight && mp.y <= candleHeight + volHeight + indHeight
			if chart.showIndicator == "MACD"
				macdY = getChartY(chart, 2, chart.allmacdarr[index])
				zeroY = getChartY(chart, 2, 0)
				if selectLines(chart, mp, 2, chart.allmacdarr, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "MACD"
				end
				if selectLines(chart, mp, 2, chart.alldifarr, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "DIF"
				elsif selectLines(chart, mp, 2, chart.alldeaarr, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "DEA"
				end
			elsif chart.showIndicator == "KDJ"
				if selectLines(chart, mp, 2, chart.kdj_k, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "K"
				elsif selectLines(chart, mp, 2, chart.kdj_d, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "D"
				elsif selectLines(chart, mp, 2, chart.kdj_j, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "J"
				end
			elsif chart.showIndicator == "RSI"
				if selectLines(chart, mp, 2, chart.rsi1, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "6"
				elsif selectLines(chart, mp, 2, chart.rsi2, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "12"
				elsif selectLines(chart, mp, 2, chart.rsi3, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "24"
				end
			elsif chart.showIndicator == "BIAS"
				if selectLines(chart, mp, 2, chart.bias1, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "1"
				elsif selectLines(chart, mp, 2, chart.bias2, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "2"
				elsif selectLines(chart, mp, 2, chart.bias3, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "3"
				end
			elsif chart.showIndicator == "ROC"
				if selectLines(chart, mp, 2, chart.roc, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "ROC"
				elsif selectLines(chart, mp, 2, chart.roc_ma, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "ROCMA"
				end
			elsif chart.showIndicator == "WR"
				if selectLines(chart, mp, 2, chart.wr1, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "1"
				elsif selectLines(chart, mp, 2, chart.wr2, index)
					chart.selectShape = "WR"
					chart.selectShapeEx = "2"
				end
			elsif chart.showIndicator == "CCI"
				if (selectLines(chart, mp, 2, chart.cci, index))
					chart.selectShape = chart.showIndicator
				end
			elsif chart.showIndicator == "BBI"
				if (selectLines(chart, mp, 2, chart.bbi, index))
					chart.selectShape = chart.showIndicator
				end
			elsif chart.showIndicator == "TRIX"
				if selectLines(chart, mp, 2, chart.trix, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "TRIX"
				elsif selectLines(chart, mp, 2, chart.trix_ma, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "TRIXMA"
				end
			elsif chart.showIndicator == "DMA"
				if selectLines(chart, mp, 2, chart.dma1, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "DIF"
				elsif selectLines(chart, mp, 2, chart.dma2, index)
					chart.selectShape = chart.showIndicator
					chart.selectShapeEx = "DIFMA"
				end
			end
		elsif mp.y >= candleHeight && mp.y <= candleHeight + volHeight
			volY = getChartY(chart, 1, chart.data[index].volume)
			zeroY = getChartY(chart, 1, 0)
			if mp.y >= [volY, zeroY].min && mp.y <= [volY, zeroY].max
				chart.selectShape = "VOL"
			end
		elsif mp.y >= 0 && mp.y <= candleHeight
			isTrend = false
			if chart.cycle == "trend"
				isTrend = true
			end
			if isTrend == false
				if chart.mainIndicator == "BOLL"
					if selectLines(chart, mp, 0, chart.boll_mid, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "MID"
					elsif selectLines(chart, mp, 0, chart.boll_up, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "UP"
					elsif selectLines(chart, mp, 0, chart.boll_down, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "DOWN"
					end
				elsif chart.mainIndicator == "MA"
					if selectLines(chart, mp, 0, chart.ma5, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "5"
					elsif selectLines(chart, mp, 0, chart.ma10, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "10"
					elsif selectLines(chart, mp, 0, chart.ma20, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "20"
					elsif selectLines(chart, mp, 0, chart.ma30, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "30"
					elsif selectLines(chart, mp, 0, chart.ma120, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "120"
					elsif selectLines(chart, mp, 0, chart.ma250, index)
						chart.selectShape = chart.mainIndicator
						chart.selectShapeEx = "250"
					end
				end
			end
			if chart.selectShape == ""
				highY = getChartY(chart, 0, chart.data[index].high)
				lowY = getChartY(chart, 0, chart.data[index].low)
				if isTrend
					if (selectLines(chart, mp, 0, chart.closearr, index))
						chart.selectShape = "CANDLE"
					end
				else
					if mp.y >= [lowY, highY].min && mp.y <= [lowY, highY].max
						chart.selectShape = "CANDLE"
					end
				end
			end
		end
		if chart.shapes.length > 0
			for i in 0..chart.shapes.length - 1
				shape = chart.shapes[i]
				if shape.leftOrRight
					if selectLines(chart, mp, shape.divIndex, shape.datas, index)
						chart.selectShape = shape.shapeName
						break
					end
				else
					if selectLinesInRight(chart, mp, shape.divIndex, shape.datas, index)
						chart.selectShape = shape.shapeName
						break
					end
				end
			end
		end
	end
end

#绘制线条
#chart:图表
#paint:绘图对象
#clipRect:裁剪区域
#divIndex:图层
#datas:数据
#color:颜色
#selected:是否选中
def drawChartLines(chart, paint, clipRect, divIndex, datas, color, selected)
	maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart))
	lastValidIndex = chart.lastVisibleIndex
	if chart.lastValidIndex != -1
		lastValidIndex = chart.lastValidIndex
	end
	drawPoints = []
	for i in chart.firstVisibleIndex..lastValidIndex
		x = getChartX(chart, i)
		value = datas[i]
		y = getChartY(chart, divIndex, value)
		drawPoints.push(FCPoint.new(x, y))
		if selected
			kPInterval = (maxVisibleRecord / 30).to_i
			if kPInterval < 2
				kPInterval = 3
			end
			if i % kPInterval == 0
				paint.fillRect(color, x - 3, y - 3, x + 3, y + 3)
			end
		end
	end
	paint.drawPolyline(color, chart.lineWidthChart, 0, drawPoints)
end

#绘制线条到右轴
#chart:图表
#paint:绘图对象
#clipRect:裁剪区域
#divIndex:图层
#datas:数据
#color:颜色
#selected:是否选中
def drawChartLinesInRight(chart, paint, clipRect, divIndex, datas, color, selected)
	maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart))
	lastValidIndex = chart.lastVisibleIndex
	if chart.lastValidIndex != -1
		lastValidIndex = chart.lastValidIndex
	end
	drawPoints = []
	for i in chart.firstVisibleIndex..lastValidIndex
		x = getChartX(chart, i)
		value = datas[i]
		y = getChartYInRight(chart, divIndex, value)
		drawPoints.push(FCPoint.new(x, y))
		if selected
			kPInterval = (maxVisibleRecord / 30).to_i
			if kPInterval < 2
				kPInterval = 3
			end
			if i % kPInterval == 0
				paint.fillRect(color, x - 3, y - 3, x + 3, y + 3)
			end
		end
	end
	paint.drawPolyline(color, chart.lineWidthChart, 0, drawPoints)
end

#数值转字符串，可以设置保留位数
#value 数值
#digit 小数位数
def toFixed(value, digit)
	roundValue = value.round(digit)
	return roundValue.to_s
end

#计算EMA
#n:周期
#value:当前数据
#lastEMA:上期数据
def getEMA(n, value, lastEMA)
	return(value * 2 + lastEMA * (n - 1)) / (n + 1)
end

#计算MACD
#dif:DIF数据
#dea:DEA数据
def getMACD(dif, dea)
	result = []
	for i in 0..dif.length - 1
		result.push((dif[i] - dea[i]) * 2)
	end
	return result
end

#计算DIF
#close12:12日数据
#close26:26日数据
def getDIF(close12, close26)
	result = []
	for i in 0..close12.length - 1
		result.push(close12[i] - close26[i])
	end
	return result
end

#REF函数
#ticks:数据
#days:日数
def REF(ticks, days)
	refArr = []
	length = ticks.length
	for i in 0..length - 1
		ref = 0
		if i >= days
			ref = ticks[i - days]
		else
			ref = ticks[0]
		end
		refArr.push(ref)
	end
	return refArr
end

#计算最大值
#ticks 最高价数组
#days
def HHV(ticks, days)
	hhv = []
	maxValue = ticks[0]
	for i in 0..ticks.length - 1
		if i >= days
			maxValue = ticks[i]
			j = i
			while j > i - days
				if maxValue < ticks[j]
					maxValue = ticks[j]
				end
				j = j - 1
			end
			hhv.push(maxValue)
		else
			if maxValue < ticks[i]
				maxValue = ticks[i]
			end
			hhv.push(maxValue)
		end
	end
	return hhv
end

#计算最小值
#ticks 最低价数组
#days
def LLV(ticks, days)
	llv = []
	minValue = ticks[0]
	for i in 0..ticks.length - 1
		if i >= days
			minValue = ticks[i]
			j = i
			while j > i - days
				if minValue > ticks[j]
					minValue = ticks[j]
				end
				j = j - 1
			end
			llv.push(minValue)
		else
			if minValue > ticks[i]
				minValue = ticks[i]
			end
			llv.push(minValue)
		end
	end
	return llv
end

#MA数据计算
#ticks 收盘价数组
#days 天数
def MA(ticks, days)
	maSum = 0
	mas = []
	last = 0
	for i in 0..ticks.length - 1
		ma = 0
		if i >= days
			last = ticks[i - days]
			maSum = maSum + ticks[i] - last
			ma = maSum / days
		else
			maSum += ticks[i]
			ma = maSum / (i + 1)
		end
		mas.push(ma)
	end
	return mas
end

#计算ROC数据
#ticks 收盘价数组
def getRocData(ticks, n, m, roc, maroc)
	for i in 0..ticks.length - 1
		currRoc = 0
		if i >= n
			currRoc = 100 * (ticks[i] - ticks[i - n]) / ticks[i - n]
			roc.push(currRoc)
		else
			currRoc = 100 * (ticks[i] - ticks[0]) / ticks[0]
			roc.append(currRoc)
		end
	end
	marocMA = MA(roc, m)
	for i in 0..marocMA.length - 1
		maroc.append(marocMA[i])
	end
end

#计算rsi指标,分别返回以6日，12日，24日为参考基期的RSI值
def getRSIData(ticks, n1, n2, n3, rsi1, rsi2, rsi3)
	lastClosePx = ticks[0]
	lastSm1 = 0
	lastSa1 = 0
	lastSm2 = 0
	lastSa2 = 0
	lastSm3 = 0
	lastSa3 = 0
	for i in 0..ticks.length - 1
		c = ticks[i]
		m = [c - lastClosePx, 0].max
		a = (c - lastClosePx).abs
		if i == 0
			lastSm1 = 0
			lastSa1 = 0
			rsi1.push(0)
		else
			lastSm1 = (m + (n1 - 1) * lastSm1) / n1
			lastSa1 = (a + (n1 - 1) * lastSa1)/ n1
			if lastSa1 != 0
				rsi1.push(100 * lastSm1 / lastSa1)
			else
				rsi1.push(0)
			end
		end
		if i == 0
			lastSm2 = 0
			lastSa2 = 0
			rsi2.push(0)
		else
			lastSm2 = (m + (n2 - 1) * lastSm2) / n2
			lastSa2 = (a + (n2 - 1) * lastSa2)/ n2
			if lastSa2 != 0
				rsi2.push(100 * lastSm2 / lastSa2)
			else
				rsi2.push(0)
			end
		end
		if i == 0
			lastSm3 = 0
			lastSa3 = 0
			rsi3.push(0)
		else
			lastSm3 = (m + (n3 - 1) * lastSm3) / n3
			lastSa3 = (a + (n3 - 1) * lastSa3)/ n3
			if lastSa3 != 0
				rsi3.push(100 * lastSm3 / lastSa3)
			else
				rsi3.push(0.0)
			end
		end
		lastClosePx = c
	end
end

#获取方差数据
def standardDeviationSum(listValue, avg_value, param)
	target_value = listValue[listValue.length - 1]
	sumValue = (target_value - avg_value) * (target_value - avg_value)
	for i in 0..listValue.length - 2
		ileft = listValue[i]
		sumValue = sumValue + (ileft - avg_value) * (ileft - avg_value)
	end
	return sumValue
end

#计算boll指标,ma的周期为20日
def getBollData(ticks, maDays, ups, mas, lows)
	tickBegin = maDays - 1
	maSum  = 0
	p = 0
	for i in 0..ticks.length - 1
		c = ticks[i]
		ma = 0
		md = 0
		bstart = 0
		mdSum = 0
		maSum = maSum + c
		if i >= tickBegin
			maSum = maSum - p
			ma = maSum / maDays
			bstart = i - tickBegin
			p = ticks[bstart]
			mas.push(ma)
			bstart = i - tickBegin
			p = ticks[bstart]
			values = []
			for j in bstart..bstart + maDays - 1
				values.push(ticks[j])
			end
			mdSum = standardDeviationSum(values, ma, 2)
			md = Math.sqrt(mdSum / maDays)
			ups.push(ma + 2 * md)
			lows.push(ma - 2 * md)
		else
			ma = maSum / (i + 1)
			mas.push(ma)
			values = []
			for j in 0..i
				values.push(ticks[j])
			end
			mdSum = standardDeviationSum(values, ma, 2)
			md = Math.sqrt(mdSum / (i + 1))
			ups.push(ma + 2 * md)
			lows.push(ma - 2 * md)
		end
	end
end

#获取最大最小值区间
#ticks:数据
def getMaxHighAndMinLow(chart, highArr, lowArr)
	for i in 0..lowArr.length - 1
		high = highArr[i]
		low = lowArr[i]
		if high > chart.nMaxHigh
			chart.nMaxHigh = high
		end
		if low < chart.nMaxLow
			chart.nMaxLow = low
		end
	end
end

#计算kdj指标,rsv的周期为9日
def getKDJData(chart, highArr, lowArr, closeArr, n, m1, m2, ks, ds, js)
	rsvs = []
	lastK = 0
	lastD = 0
	curK = 0
	curD = 0
	for i in 0..highArr.length - 1
		highList = []
		lowList = []
		startIndex = i - n
		if startIndex < 0
			startIndex = 0
		end
		for j in startIndex..i
			highList.push(highArr[j])
			lowList.push(lowArr[j])
		end
		chart.nMaxHigh = 0
		chart.nMaxLow = 0
		close = closeArr[i]
		getMaxHighAndMinLow(chart, highList, lowList)
		if chart.nMaxHigh == chart.nMaxLow
			rsvs.push(0)
		else
			rsvs.push(100 * (close - chart.nMaxLow) / (chart.nMaxHigh - chart.nMaxLow))
		end
		if i == 0
			lastK = rsvs[i]
			lastD = rsvs[i]
		end
		curK = lastK * (m1 - 1) / m1 + rsvs[i] * 1.0 / m1
		ks.push(curK)
		lastK = curK

		curD = lastD * (m2 - 1) / m2 + curK * 1.0 / m2
		ds.push(curD)
		lastD = curD

		js.push(3.0 * curK - 2.0 * curD)
	end
end

#获取BIAS的数据
#ticks 收盘价数组
def getBIASData(ticks, n1, n2, n3, bias1Arr, bias2Arr, bias3Arr)
	ma1 = MA(ticks, n1)
	ma2 = MA(ticks, n2)
	ma3 = MA(ticks, n3)
	for i in 0..ticks.length - 1
		b1 = 100 * (ticks[i] - ma1[i]) / ma1[i]
		b2 = 100 * (ticks[i] - ma2[i]) / ma2[i]
		b3 = 100 * (ticks[i] - ma3[i]) / ma3[i]
		bias1Arr.push(b1)
		bias2Arr.push(b2)
		bias3Arr.push(b3)
	end
end

#计算DMA（平均差）
#ticks 收盘价数组
def getDMAData(ticks, n1, n2, difArr, difmaArr)
	ma10 = MA(ticks, n1)
	ma50 = MA(ticks, n2)
	for i in 0..ticks.length - 1
		dif = ma10[i] - ma50[i]
		difArr.push(dif)
	end
	difma = MA(difArr, n1)
	for i in 0..difma.length - 1
		difmaArr.push(difma[i])
	end
end

#计算BBI(多空指标)
#ticks
def getBBIData(ticks, n1, n2, n3, n4, bbiArr)
	ma3 = MA(ticks, n1)
	ma6 = MA(ticks, n2)
	ma12 = MA(ticks, n3)
	ma24 = MA(ticks, n4)
	for i in 0..ticks.length - 1
		bbi = (ma3[i] + ma6[i] + ma12[i] + ma24[i]) / 4
		bbiArr.push(bbi)
	end
end

#计算WR(威廉指标)
#ticks 含最高价,最低价, 收盘价的二维数组
#days
def getWRData(closeArr, highArr, lowArr, n1, n2, wr1Arr, wr2Arr)
	for i in 0..closeArr.length - 1
		highArr.push(highArr[i])
		lowArr.push(lowArr[i])
		closeArr.push(closeArr[i])
	end
	highArr1 = HHV(highArr, n1)
	highArr2 = HHV(highArr, n2)
	lowArr1 = LLV(lowArr, n1)
	lowArr2 = LLV(lowArr, n2)
	for i in 0..closeArr.length - 1
		high1 = highArr1[i]
		low1 = lowArr1[i]
		high2 = highArr2[i]
		low2 = lowArr2[i]
		close = closeArr[i]
		wr1 = 100 * (high1 - close) / (high1 - low1)
		wr2 = 100 * (high2 - close) / (high2 - low2)
		wr1Arr.push(wr1)
		wr2Arr.push(wr2)
	end
end

#CCI(顺势指标)计算  CCI（N日）=（TP－MA）÷MD÷0.015
#ticks 带最高价，最低价，收盘价的二维数组
def getCCIData(closeArr, highArr, lowArr, n, cciArr)
	tpArr = []
	for i in 0..closeArr.length - 1
		tpArr.push((closeArr[i] + highArr[i] + lowArr[i]) / 3)
	end
	maClose = MA(closeArr, n)

	mdArr = []
	for i in 0..closeArr.length - 1
		mdArr.push(maClose[i] - closeArr[i])
	end

	maMD = MA(mdArr, n)
	for i in 0..closeArr.length - 1
		cci = 0
		if maMD[i] > 0
			cci = (tpArr[i] - maClose[i]) / (maMD[i] * 0.015)
		end
		cciArr.push(cci)
	end
	return cciArr
end

#获取TRIX的数据
#ticks:数据
def getTRIXData(ticks, n, m, trixArr, matrixArr)
	mtrArr = []
	emaArr1 = []
	emaArr1.push(ticks[0])
	for i in 1..ticks.length - 1
		emaArr1.push(getEMA(n, ticks[i], emaArr1[i - 1]))
	end

	emaArr2 = []
	emaArr2.push(emaArr1[0])
	for i in 1..ticks.length - 1
		emaArr2.push(getEMA(n, emaArr1[i], emaArr2[i - 1]))
	end

	mtrArr.push(emaArr2[0])
	for i in 1..ticks.length - 1
		mtrArr.push(getEMA(n, emaArr2[i], mtrArr[i - 1]))
	end

	ref = REF(mtrArr, 1)
	for i in 0..ticks.length - 1
		trix = 100 * (mtrArr[i] - ref[i]) / ref[i]
		trixArr.push(trix)
	end
	matrixMa = MA(trixArr, m)
	for i in 0..matrixMa.length - 1
		matrixArr.push(matrixMa[i])
	end
end

#绘制画线工具
#chart:图表
#pPaint:绘图对象
#clipRect:裁剪区域
def drawChartPlot(chart, pPaint, clipRect)
	if chart.plots.length > 0
		paint = nil
		paint = pPaint
		divHeight = getCandleDivHeight(chart)
		paint.setClip(chart.leftVScaleWidth, 0, chart.size.cx, divHeight)
		for i in 0..chart.plots.length - 1
			plot = chart.plots[i]
			index1 = 0
			index2 = 0
			index3 = 0
			mpx1 = 0
			mpy1 = 0
			mpx2 = 0
			mpy2 = 0
			mpx3 = 0
			mpy3 = 0
			if plot.plotType == "LRLine" || plot.plotType == "LRChannel" || plot.plotType == "LRBand"
				listValue = []
				index1 = getChartIndexByDate(chart, plot.key1)
				index2 = getChartIndexByDate(chart, plot.key2)
				minIndex = [index1, index2].min
				maxIndex = [index1, index2].max
				for j in minIndex..maxIndex
					listValue.push(chart.data[j].close)
				end
				linearRegressionEquation(chart, listValue)
				plot.value1 = chart.bChart
				plot.value2 = chart.kChart * (maxIndex - minIndex + 1) + chart.bChart
			elsif plot.plotType == "BoxLine" || plot.plotType == "TironeLevels" || plot.plotType == "QuadrantLines"
				getCandleRange(chart, plot)
				nHigh = chart.nHighChart
				nLow = chart.nLowChart
				index1 = getChartIndexByDate(chart, plot.key1)
				index2 = getChartIndexByDate(chart, plot.key2)
				plot.key1 = getChartDateByIndex(chart, [index1, index2].min)
				plot.key2 = getChartDateByIndex(chart, [index1, index2].max)
				plot.value1 = nHigh
				plot.value2 = nLow
			end
			if plot.key1 != nil
				index1 = getChartIndexByDate(chart, plot.key1)
				mpx1 = getChartX(chart, index1)
				mpy1 = getChartY(chart, 0, plot.value1)
				if chart.sPlot == plot
					paint.fillEllipse(plot.pointColor, mpx1 - chart.plotPointSizeChart, mpy1 - chart.plotPointSizeChart, mpx1 + chart.plotPointSizeChart, mpy1 + chart.plotPointSizeChart)
				end
			end
			if plot.key2 != nil
				index2 = getChartIndexByDate(chart, plot.key2)
				mpx2 = getChartX(chart, index2)
				mpy2 = getChartY(chart, 0, plot.value2)
				if chart.sPlot == plot
					paint.fillEllipse(plot.pointColor, mpx2 - chart.plotPointSizeChart, mpy2 - chart.plotPointSizeChart, mpx2 + chart.plotPointSizeChart, mpy2 + chart.plotPointSizeChart)
				end
			end
			if plot.key3 != nil
				index3 = getChartIndexByDate(chart, plot.key3)
				mpx3 = getChartX(chart, index3)
				mpy3 = getChartY(chart, 0, plot.value3)
				if chart.sPlot == plot
					paint.fillEllipse(plot.pointColor, mpx3 - chart.plotPointSizeChart, mpy3 - chart.plotPointSizeChart, mpx3 + chart.plotPointSizeChart, mpy3 + chart.plotPointSizeChart)
				end
			end
			if plot.plotType == "Line"
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				if mpx2 == mpx1
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, 0, mpx1, divHeight)
				else
					newX1 = chart.leftVScaleWidth
					newY1 = newX1 * chart.kChart + chart.bChart
					newX2 = chart.size.cx - chart.rightVScaleWidth
					newY2 = newX2 * chart.kChart + chart.bChart
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, newX1, newY1, newX2, newY2)
				end
			elsif plot.plotType == "ArrowSegment"
				arrowSize = 24
				slopy = 0
				cosy = 0
				siny = 0
				slopy = Math.atan2(mpy1 - mpy2, mpx1 - mpx2)
				cosy = Math.cos(slopy)
				siny = Math.sin(slopy)
				ptPoint = FCPoint.new(0,0)
				ptPoint.x = mpx2
				ptPoint.y = mpy2
				pts = []
				pts.push(FCPoint.new(0, 0))
				pts.push(FCPoint.new(0, 0))
				pts.push(FCPoint.new(0, 0))
				pts[0] = ptPoint
				pts[1].x = ptPoint.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)
				pts[1].y = ptPoint.y + (arrowSize * siny + (arrowSize / 2.0 * cosy) + 0.5)
				pts[2].x = ptPoint.x + (arrowSize * cosy + arrowSize / 2.0 * siny + 0.5)
				pts[2].y = ptPoint.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5)
				arrowSize = 20
				ptPoint2 = FCPoint.new(0,0)
				ptPoint2.x = mpx2
				ptPoint2.y = mpy2
				pts2 = []
				pts2.push(FCPoint.new(0, 0))
				pts2.push(FCPoint.new(0, 0))
				pts2.push(FCPoint.new(0, 0))
				pts2[0] = ptPoint2
				pts2[1].x = ptPoint2.x + (arrowSize * cosy - (arrowSize / 2.0 * siny) + 0.5)
				pts2[1].y = ptPoint2.y + (arrowSize * siny + (arrowSize / 2.0 * cosy) + 0.5)
				pts2[2].x = ptPoint2.x + (arrowSize * cosy + arrowSize / 2.0 * siny + 0.5)
				pts2[2].y = ptPoint2.y - (arrowSize / 2.0 * cosy - arrowSize * siny + 0.5)
				lineXY(chart, pts2[1].x, pts2[1].y, pts2[2].x, pts2[2].y, 0, 0)
				newX1 = 0
				newY1 = 0
				newX2 = 0
				newY2 = 0

				if pts2[1].x > pts2[2].x
					newX1 = pts2[2].x + (pts2[1].x - pts2[2].x) / 3
					newX2 = pts2[2].x + (pts2[1].x - pts2[2].x) * 2 / 3
				else
					newX1 = pts2[1].x + (pts2[2].x - pts2[1].x) / 3
					newX2 = pts2[1].x + (pts2[2].x - pts2[1].x) * 2 / 3
				end
				if chart.kChart == 0 && chart.bChart == 0
					if pts2[1].y > pts2[2].y
						newY1 = pts2[2].y + (pts2[1].y - pts2[2].y) / 3
						newY2 = pts2[2].y + (pts2[1].y - pts2[2].y) * 2 / 3
					else
						newY1 = pts2[1].y + (pts2[2].y - pts2[1].y) / 3
						newY2 = pts2[1].y + (pts2[2].y - pts2[1].y) * 2 / 3
					end
				else
					newY1 = (chart.kChart * newX1) + chart.bChart
					newY2 = (chart.kChart * newX2) + chart.bChart
				end
				pts2[1].x = newX1
				pts2[1].y = newY1
				pts2[2].x = newX2
				pts2[2].y = newY2
				drawPoints = []
				drawPoints.push(FCPoint.new(0, 0))
				drawPoints.push(FCPoint.new(0, 0))
				drawPoints.push(FCPoint.new(0, 0))
				drawPoints.push(FCPoint.new(0, 0))
				drawPoints.push(FCPoint.new(0, 0))
				drawPoints.push(FCPoint.new(0, 0))
				drawPoints[0].x = ptPoint.x
				drawPoints[0].y = ptPoint.y
				drawPoints[1].x = pts[1].x
				drawPoints[1].y = pts[1].y
				if mpy1 >= mpy2
					drawPoints[2].x = pts2[1].x
					drawPoints[2].y = pts2[1].y
				else
					drawPoints[2].x = pts2[2].x
					drawPoints[2].y = pts2[2].y
				end
				drawPoints[3].x = mpx1
				drawPoints[3].y = mpy1
				if mpy1 >= mpy2
					drawPoints[4].x = pts2[2].x
					drawPoints[4].y = pts2[2].y
				else
					drawPoints[4].x = pts2[1].x
					drawPoints[4].y = pts2[1].y
				end
				drawPoints[5].x = pts[2].x
				drawPoints[5].y = pts[2].y
				paint.fillPolygon(plot.lineColor, drawPoints)
			elsif plot.plotType == "AngleLine"
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				if mpx2 == mpx1
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, 0, mpx1, divHeight)
				else
					newX1 = chart.leftVScaleWidth
					newY1 = newX1 * chart.kChart + chart.bChart
					newX2 = chart.size.cx - chart.rightVScaleWidth
					newY2 = newX2 * chart.kChart + chart.bChart
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, newX1, newY1, newX2, newY2)
				end
				lineXY(chart, mpx1, mpy1, mpx3, mpy3, 0, 0)
				if mpx3 == mpx1
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, 0, mpx1, divHeight)
				else
					newX1 = chart.leftVScaleWidth
					newY1 = newX1 * chart.kChart + chart.bChart
					newX2 = chart.size.cx - chart.rightVScaleWidth
					newY2 = newX2 * chart.kChart + chart.bChart
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, newX1, newY1, newX2, newY2)
				end
			elsif plot.plotType == "Parallel"
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				if mpx2 == mpx1
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, 0, mpx1, divHeight)
				else
					newX1 = chart.leftVScaleWidth
					newY1 = newX1 * chart.kChart + chart.bChart
					newX2 = chart.size.cx - chart.rightVScaleWidth
					newY2 = newX2 * chart.kChart + chart.bChart
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, newX1, newY1, newX2, newY2)
					newB = mpy3 - chart.kChart * mpx3
				end
				if mpx2 == mpx1
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx3, 0, mpx3, divHeight)
				else
					newX1 = chart.leftVScaleWidth
					newY1 = newX1 * chart.kChart + newB
					newX2 = chart.size.cx - chart.rightVScaleWidth
					newY2 = newX2 * chart.kChart + newB
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, newX1, newY1, newX2, newY2)
				end
			elsif plot.plotType == "Percent"
				listValue = getPercentParams(mpy1, mpy2)
				texts = []
				texts.push("0%")
				texts.push("25%")
				texts.push("50%")
				texts.push("75%")
				texts.push("100%")
				for j in 0..listValue.length - 1
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, chart.leftVScaleWidth, listValue[j], chart.size.cx - chart.rightVScaleWidth, listValue[j])
					tSize = paint.textSize(texts[j], chart.font)
					paint.drawText(texts[j], chart.textColor, chart.font, chart.leftVScaleWidth + 5, listValue[j] - tSize.cy - 2)
				end
			elsif plot.plotType == "FiboTimezone"
				fValue = 1
				aIndex = index1
				pos = 1
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, 0, mpx1, divHeight)
				tSize = paint.textSize("1", chart.font)
				paint.drawText("1", chart.textColor, chart.font, mpx1, divHeight - tSize.cy)
				while aIndex + fValue <= chart.lastVisibleIndex
					fValue = fibonacciValue(pos)
					newIndex = aIndex + fValue
					newX = getChartX(chart, newIndex)
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, newX, 0, newX, divHeight)
					tSize = paint.textSize(fValue.to_s, chart.font)
					paint.drawText(fValue.to_s, chart.textColor, chart.font, newX, divHeight - tSize.cy)
					pos = pos + 1
				end
			elsif plot.plotType == "SpeedResist"
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
				if mpx1 != mpx2 && mpy1 != mpy2
					firstP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) / 3)
					secondP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 2 / 3)
					startP = FCPoint.new(mpx1, mpy1)
					fK = 0
					fB = 0
					sK = 0
					sB = 0
					lineXY(chart, startP.x, startP.y, firstP.x, firstP.y, 0, 0)
					fK = chart.kChart
					fB = chart.bChart
					lineXY(chart, startP.x, startP.y, secondP.x, secondP.y, 0, 0)
					sK = chart.kChart
					sB = chart.bChart
					newYF = 0
					newYS = 0
					newX = 0
					if mpx2 > mpx1
						newYF = fK * (chart.size.cx - chart.rightVScaleWidth) + fB
						newYS = sK * (chart.size.cx - chart.rightVScaleWidth) + sB
						newX = (chart.size.cx - chart.rightVScaleWidth)
					else
						newYF = fB
						newYS = sB
					end
					newX = chart.leftVScaleWidth
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, startP.x, startP.y, newX, newYF)
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, startP.x, startP.y, newX, newYS)
				end
			elsif plot.plotType == "FiboFanline"
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
				if mpx1 != mpx2 && mpy1 != mpy2
					firstP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 0.382)
					secondP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 0.5)
					thirdP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 0.618)
					startP = FCPoint.new(mpx1, mpy1)
					listP = []
					listP.push(firstP)
					listP.push(secondP)
					listP.push(thirdP)
					listSize = listP.length
					for j in 0..listSize - 1
						lineXY(chart, startP.x, startP.y, listP[j].x, listP[j].y, 0, 0)
						newX = 0
						newY = 0
						if mpx2 > mpx1
							newY = chart.kChart * (chart.size.cx - chart.rightVScaleWidth) + chart.bChart
							newX = (chart.size.cx - chart.rightVScaleWidth)
						else
							newY = chart.bChart
							newX = chart.leftVScaleWidth
						end
						paint.drawLine(plot.lineColor, plot.lineWidth, 0, startP.x, startP.y, newX, newY)
					end
				end
			elsif plot.plotType == "LRLine"
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "LRBand"
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
				getLRBandRange(chart, plot, chart.kChart, chart.bChart)
				mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue)
				mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
				mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue)
				mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "LRChannel"
				getLRBandRange(chart, plot, chart.kChart, chart.bChart)
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				rightX = chart.size.cx - chart.rightVScaleWidth
				rightY = rightX * chart.kChart + chart.bChart
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, rightX, rightY)
				mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue)
				mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue)
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				rightY = rightX * chart.kChart + chart.bChart
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, rightX, rightY)
				mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue)
				mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue)
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				rightY = rightX * chart.kChart + chart.bChart
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, rightX, rightY)
			elsif plot.plotType == "Segment"
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "Ray"
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				if chart.kChart != 0 || chart.bChart != 0
					leftX = chart.leftVScaleWidth
					leftY = leftX * chart.kChart + chart.bChart
					rightX = chart.size.cx - chart.rightVScaleWidth
					rightY = rightX * chart.kChart + chart.bChart
					if mpx1 >= mpx2
						paint.drawLine(plot.lineColor, plot.lineWidth, 0, leftX, leftY, mpx1, mpy1)
					else
						paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, rightX, rightY)
					end
				else
					if mpy1 >= mpy2
						paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx1, 0)
					else
						paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx1, divHeight)
					end
				end
			elsif plot.plotType == "Triangle"
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx2, mpy2, mpx3, mpy3)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx3, mpy3)
			elsif plot.plotType == "SymmetricTriangle"
				if mpx2 != mpx1
					a = (mpy2 - mpy1) / (mpx2 - mpx1)
					b = mpy1 - a * mpx1
					c = -a
					d = mpy3 - c * mpx3
					leftX = chart.leftVScaleWidth
					leftY = leftX * a + b
					rightX = chart.size.cx - chart.rightVScaleWidth
					rightY = rightX * a + b
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, leftX, leftY, rightX, rightY)
					leftY = leftX * c + d
					rightY = rightX * c + d
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, leftX, leftY, rightX, rightY)
				else
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, 0, mpx1, divHeight)
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx3, 0, mpx3, divHeight)
				end
			elsif plot.plotType == "Rect"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				paint.drawRect(plot.lineColor, plot.lineWidth, 0, sX1, sY1, sX2, sY2)
			elsif plot.plotType == "Cycle"
				r = Math.sqrt(((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1)).abs)
				paint.drawEllipse(plot.lineColor, plot.lineWidth, 0, mpx1 - r, mpy1 - r, mpx1 + r, mpy1 + r)
			elsif plot.plotType == "CircumCycle"
				ellipseOR(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3)
				paint.drawEllipse(plot.lineColor, plot.lineWidth, 0, chart.oXChart - chart.rChart, chart.oYChart - chart.rChart, chart.oXChart + chart.rChart, chart.oYChart + chart.rChart)
			elsif plot.plotType == "Ellipse"
				x1 = 0
				y1 = 0
				x2 = 0
				y2 = 0
				if mpx1 <= mpx2
					x1 = mpx2
					y1 = mpy2
					x2 = mpx1
					y2 = mpy1
				else
					x1 = mpx1
					y1 = mpy1
					x2 = mpx2
					y2 = mpy2	
				end
				x = x1 - (x1 - x2)
				y = 0
				width = (x1 - x2) * 2
				height = 0
				if y1 >= y2
					height = (y1 - y2) * 2
				else
					height = (y2 - y1) * 2
				end
				y = y2 - height / 2
				paint.drawEllipse(plot.lineColor, plot.lineWidth, 0, x, y, x + width, y + height)
			elsif plot.plotType == "ParalleGram"
				parallelogram(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx1, mpy1, mpx2, mpy2)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx2, mpy2, mpx3, mpy3)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, mpx3, mpy3, chart.x4Chart, chart.y4Chart)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, chart.x4Chart, chart.y4Chart, mpx1, mpy1)
			elsif plot.plotType == "BoxLine"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				paint.drawRect(plot.lineColor, plot.lineWidth, 0, sX1, sY1, sX2, sY2)
				bSize = paint.textSize("COUNT:" + ((index2 - index1).abs + 1).to_s, chart.font)
				paint.drawText("COUNT:" + ((index2 - index1).abs + 1).to_s, chart.textColor, chart.font, sX1 + 2, sY1 + 2)
				closeList = []
				for j in index1..index2
					closeList.push(chart.data[j].close)
				end
				avgClose = avgValue(closeList)
				closeY = getChartY(chart, 0, avgClose)
				paint.drawLine(plot.lineColor, plot.lineWidth, 1, sX1, closeY, sX2, closeY)
				drawAvg = "AVG:" + toFixed(avgClose, chart.candleDigit)
				tSize = paint.textSize(drawAvg, chart.font)
				paint.drawText(drawAvg, chart.textColor, chart.font, sX1 + 2, closeY - tSize.cy - 2)
			elsif plot.plotType == "TironeLevels"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, sX1, sY1, sX2, sY1)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, sX1, sY2, sX2, sY2)
				paint.drawLine(plot.lineColor, plot.lineWidth, [5, 5], sX1 + (sX2 - sX1) / 2, sY1, sX1 + (sX2 - sX1) / 2, sY2)
				t1 = chart.nHighChart
				t2 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 3
				t3 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 2
				t4 = chart.nHighChart - 2 * (chart.nHighChart - chart.nLowChart) / 3
				t5 = chart.nLowChart
				tList = []
				tList.push(t2)
				tList.push(t3)
				tList.push(t4)
				for j in 0..tList.length - 1
					y = getChartY(chart, 0, tList[j])
					paint.drawLine(plot.lineColor, plot.lineWidth, [5,5], chart.leftVScaleWidth, y, chart.size.cx - chart.rightVScaleWidth, y)
					strText = toFixed(tList[j], chart.candleDigit)
					tSize = paint.textSize(strText, chart.font)
					paint.drawText(strText, chart.textColor, chart.font, chart.leftVScaleWidth + 2, y - tSize.cy - 2)
				end
			elsif plot.plotType == "QuadrantLines"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, sX1, sY1, sX2, sY1)
				paint.drawLine(plot.lineColor, plot.lineWidth, 0, sX1, sY2, sX2, sY2)
				t1 = chart.nHighChart
				t2 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 4
				t3 = chart.nHighChart - (chart.nHighChart - chart.nLowChart) / 2
				t4 = chart.nHighChart - 3 * (chart.nHighChart - chart.nLowChart) / 4
				t5 = chart.nLowChart
				tList = []
				tList.push(t2)
				tList.push(t3)
				tList.push(t4)
				for j in 0..tList.length - 1
					y = getChartY(chart, 0, tList[j])
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, sX1, y, sX2, y)
				end
			elsif plot.plotType == "GoldenRatio"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				ranges = []
				ranges.push(0)
				ranges.push(0.236)
				ranges.push(0.382)
				ranges.push(0.5)
				ranges.push(0.618)
				ranges.push(0.809)
				ranges.push(1)
				ranges.push(1.382)
				ranges.push(1.618)
				ranges.push(2)
				ranges.push(2.382)
				ranges.push(2.618)
				minValue = [plot.value1, plot.value2].min
				maxValue = [plot.value1, plot.value2].max
				for j in 0..ranges.length - 1
					newY = sY2 + (sY1 - sY2) * (1 - ranges[j])
					if sY1 <= sY2
						newY = sY1 + (sY2 - sY1) * ranges[j]
					end
					paint.drawLine(plot.lineColor, plot.lineWidth, 0, chart.leftVScaleWidth, newY, chart.size.cx - chart.rightVScaleWidth, newY)
					newPoint = FCPoint.new(0, newY)
					value = getCandleDivValue(chart, newPoint)
					strText = toFixed(value, chart.candleDigit)
					tSize = paint.textSize(strText, chart.font)
					paint.drawText(strText, chart.textColor, chart.font, chart.leftVScaleWidth + 2, newY - tSize.cy - 2)
				end
			end
		end
		paint.setClip(0, 0, chart.size.cx, chart.size.cy)
	end
end

#选中直线
#chart: 图表
#mp:坐标
def selectPlot(chart, mp)
	sPlot = nil
	chart.startMovePlot = false
	chart.selectPlotPoint = -1
	for i in 0..chart.plots.length - 1
		plot = chart.plots[i]
		index1 = 0
		index2 = 0
		index3 = 0
		mpx1 = 0
		mpy1 = 0
		mpx2 = 0
		mpy2 = 0
		mpx3 = 0
		mpy3 = 0
		if plot.key1 != nil
			index1 = getChartIndexByDate(chart, plot.key1)
			mpx1 = getChartX(chart, index1)
			mpy1 = getChartY(chart, 0, plot.value1)
			if mp.x >= mpx1 - chart.plotPointSizeChart && mp.x <= mpx1 + chart.plotPointSizeChart && mp.y >= mpy1 - chart.plotPointSizeChart && mp.y <= mpy1 + chart.plotPointSizeChart
				sPlot = plot
				chart.selectPlotPoint = 0
				break
			end
		end
		if plot.key2 != nil
			index2 = getChartIndexByDate(chart, plot.key2)
			mpx2 = getChartX(chart, index2)
			mpy2 = getChartY(chart, 0, plot.value2)
			if mp.x >= mpx2 - chart.plotPointSizeChart && mp.x <= mpx2 + chart.plotPointSizeChart && mp.y >= mpy2 - chart.plotPointSizeChart && mp.y <= mpy2 + chart.plotPointSizeChart
				sPlot = plot
				chart.selectPlotPoint = 1
				break
			end
		end
		if plot.key3 != nil
			index3 = getChartIndexByDate(chart, plot.key3)
			mpx3 = getChartX(chart, index3)
			mpy3 = getChartY(chart, 0, plot.value3)
			if mp.x >= mpx3 - chart.plotPointSizeChart && mp.x <= mpx3 + chart.plotPointSizeChart && mp.y >= mpy3 - chart.plotPointSizeChart && mp.y <= mpy3 + chart.plotPointSizeChart
				sPlot = plot
				chart.selectPlotPoint = 2
				break
			end
		end

		if chart.selectPlotPoint == -1
			if plot.plotType == "Line"
				chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "ArrowSegment"
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "AngleLine"
				chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx2, mpy2)
				if chart.startMovePlot == false
					chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx3, mpy3)
				end
			elsif plot.plotType == "Parallel"
				chart.startMovePlot = selectLine(chart, mp, mpx1, mpy1, mpx2, mpy2)
				if chart.startMovePlot == false
					lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
					newB = mpy3 - chart.kChart * mpx3
					if mpx2 == mpx1
						if mp.x >= mpx3 - chart.plotPointSizeChart && mp.x <= mpx3 + chart.plotPointSizeChart
							chart.startMovePlot = true
						end
					else
						newX1 = chart.leftVScaleWidth
						newY1 = newX1 * chart.kChart + newB
						newX2 = chart.size.cx - chart.rightVScaleWidth
						newY2 = newX2 * chart.kChart + newB
						chart.startMovePlot = selectLine(chart, mp, newX1, newY1, newX2, newY2)
					end
				end
			elsif plot.plotType == "LRLine"
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "Segment"
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "Ray"
				chart.startMovePlot = selectRay(chart, mp, mpx1, mpy1, mpx2, mpy2)
			elsif plot.plotType == "Triangle"
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, mpx2, mpy2, mpx3, mpy3)
				end
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx3, mpy3)
				end
			elsif plot.plotType == "SymmetricTriangle"
				if mpx2 != mpx1
					a = (mpy2 - mpy1) / (mpx2 - mpx1)
					b = mpy1 - a * mpx1
					c = -a
					d = mpy3 - c * mpx3
					leftX = chart.leftVScaleWidth
					leftY = leftX * a + b
					rightX = chart.size.cx - chart.rightVScaleWidth
					rightY = rightX * a + b
					chart.startMovePlot = selectSegment(chart, mp, leftX, leftY, rightX, rightY)
					if chart.startMovePlot == false
						leftY = leftX * c + d
						rightY = rightX * c + d
						chart.startMovePlot = selectSegment(chart, mp, leftX, leftY, rightX, rightY)
					end
				else
					divHeight = getCandleDivHeight(chart)
					chart.startMovePlot = selectSegment(chart, mp, mpx1, 0, mpx1, divHeight)
					if chart.startMovePlot == false		
						chart.startMovePlot = selectSegment(chart, mp, mpx3, 0, mpx3, divHeight)
					end
				end
			elsif plot.plotType == "Rect"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1)
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX2, sY1, sX2, sY2)
				end
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2)
				end
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX1, sY2)
				end
			elsif plot.plotType == "BoxLine"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1)
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX2, sY1, sX2, sY2)
				end
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2)
				end
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX1, sY2)
				end
			elsif plot.plotType == "TironeLevels"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1)
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2)
				end
			elsif plot.plotType == "QuadrantLines"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				chart.startMovePlot = selectSegment(chart, mp, sX1, sY1, sX2, sY1)
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, sX1, sY2, sX2, sY2)
				end
			elsif plot.plotType == "GoldenRatio"
				sX1 = [mpx1, mpx2].min
				sY1 = [mpy1, mpy2].min
				sX2 = [mpx1, mpx2].max
				sY2 = [mpy1, mpy2].max
				ranges = []
				ranges.push(0)
				ranges.push(0.236)
				ranges.push(0.382)
				ranges.push(0.5)
				ranges.push(0.618)
				ranges.push(0.809)
				ranges.push(1)
				ranges.push(1.382)
				ranges.push(1.618)
				ranges.push(2)
				ranges.push(2.382)
				ranges.push(2.618)
				minValue = [plot.value1, plot.value2].min
				maxValue = [plot.value1, plot.value2].max
				for j in 0..ranges.length - 1
					newY = sY2 + (sY1 - sY2) * (1 - ranges[j])
					if sY1 <= sY2
						newY = sY1 + (sY2 - sY1) * ranges[j]
					end
					chart.startMovePlot = selectSegment(chart, mp, chart.leftVScaleWidth, newY, chart.size.cx - chart.rightVScaleWidth, newY)
					if chart.startMovePlot
						break
					end
				end
			elsif plot.plotType == "Cycle"
				r = Math.sqrt(((mpx2 - mpx1) * (mpx2 - mpx1) + (mpy2 - mpy1) * (mpy2 - mpy1)).abs)
				roundValue = (mp.x - mpx1) * (mp.x - mpx1) + (mp.y - mpy1) * (mp.y - mpy1)
				if roundValue / (r * r) >= 0.9 && roundValue / (r * r) <= 1.1
					chart.startMovePlot = true
				end
			elsif plot.plotType == "CircumCycle"
				ellipseOR(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3)
				roundValue = (mp.x - chart.oXChart) * (mp.x - chart.oXChart) + (mp.y - chart.oYChart) * (mp.y - chart.oYChart)
				if roundValue / (chart.rChart * chart.rChart) >= 0.9 && roundValue / (chart.rChart * chart.rChart) <= 1.1
					chart.startMovePlot = true
				end
			elsif plot.plotType == "Ellipse"
				x1 = 0
				y1 = 0
				x2 = 0
				y2 = 0
				if mpx1 <= mpx2
					x1 = mpx2
					y1 = mpy2
					x2 = mpx1
					y2 = mpy1
				else
					x1 = mpx1
					y1 = mpy1
					x2 = mpx2
					y2 = mpy2
				end
				x = x1 - (x1 - x2)
				y = 0
				width = (x1 - x2) * 2
				height = 0
				if y1 >= y2
					height = (y1 - y2) * 2
				else
					height = (y2 - y1) * 2
				end
				y = y2 - height / 2
				a = width / 2
				b = height / 2
				chart.startMovePlot = ellipseHasPoint(mp.x, mp.y, x + (width / 2), y + (height / 2), a, b)
			elsif plot.plotType == "LRBand"
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
				if chart.startMovePlot == false
					listValue = []
					minIndex = [index1, index2].min
					maxIndex = [index1, index2].max
					for j in minIndex..maxIndex
						listValue.push(chart.data[j].close)
					end
					linearRegressionEquation(chart, listValue)
					getLRBandRange(chart, plot, chart.kChart, chart.bChart)
					mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue)
					mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue)
					chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
					if chart.startMovePlot == false
						mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue)
						mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue)
						chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
					end
				end
			elsif plot.plotType == "LRChannel"
				lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
				rightX = chart.size.cx - chart.rightVScaleWidth
				rightY = rightX * chart.kChart + chart.bChart
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, rightX, rightY)
				if chart.startMovePlot == false
					listValue = []
					minIndex = [index1, index2].min
					maxIndex = [index1, index2].max
					for j in minIndex..maxIndex
						listValue.push(chart.data[j].close)
					end
					linearRegressionEquation(chart, listValue)
					getLRBandRange(chart, plot, chart.kChart, chart.bChart)
					mpy1 = getChartY(chart, 0, plot.value1 + chart.upSubValue)
					mpy2 = getChartY(chart, 0, plot.value2 + chart.upSubValue)
					lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
					rightY = rightX * chart.kChart + chart.bChart
					chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, rightX, rightY)
					if chart.startMovePlot == false
						mpy1 = getChartY(chart, 0, plot.value1 - chart.downSubValue)
						mpy2 = getChartY(chart, 0, plot.value2 - chart.downSubValue)
						lineXY(chart, mpx1, mpy1, mpx2, mpy2, 0, 0)
						rightY = rightX * chart.kChart + chart.bChart
						chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, rightX, rightY)
					end
				end
			elsif plot.plotType == "ParalleGram"
				parallelogram(chart, mpx1, mpy1, mpx2, mpy2, mpx3, mpy3)
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
				if chart.startMovePlot == false
					chart.startMovePlot = selectSegment(chart, mp, mpx2, mpy2, mpx3, mpy3)
					if chart.startMovePlot == false
						chart.startMovePlot = selectSegment(chart, mp, mpx3, mpy3, chart.x4Chart, chart.y4Chart)
						if chart.startMovePlot == false
							chart.startMovePlot = selectSegment(chart, mp, chart.x4Chart, chart.y4Chart, mpx1, mpy1)
						end
					end
				end
			elsif plot.plotType == "SpeedResist"
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
				if chart.startMovePlot == false
					if mpx1 != mpx2 && mpy1 != mpy2
						firstP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) / 3)
						secondP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 2 / 3)
						startP = FCPoint.new(mpx1, mpy1)
						fK = 0
						fB = 0
						sK = 0
						sB = 0
						lineXY(chart, startP.x, startP.y, firstP.x, firstP.y, 0, 0)
						fK = chart.kChart
						fB = chart.bChart
						lineXY(chart, startP.x, startP.y, secondP.x, secondP.y, 0, 0)
						sK = chart.kChart
						sB = chart.bChart
						newYF = 0
						newYS = 0
						newX = 0
						if mpx2 > mpx1
							newYF = fK * (chart.size.cx - chart.rightVScaleWidth) + fB
							newYS = sK * (chart.size.cx - chart.rightVScaleWidth) + sB
							newX = (chart.size.cx - chart.rightVScaleWidth)
						else
							newYF = fB
							newYS = sB
							newX = chart.leftVScaleWidth
						end
						chart.startMovePlot = selectSegment(chart, mp, startP.x, startP.y, newX, newYF)
						if chart.startMovePlot == false
							chart.startMovePlot = selectSegment(chart, mp, startP.x, startP.y, newX, newYS)
						end
					end
				end
			elsif plot.plotType == "FiboFanline"
				chart.startMovePlot = selectSegment(chart, mp, mpx1, mpy1, mpx2, mpy2)
				if chart.startMovePlot == false
					if mpx1 != mpx2 && mpy1 != mpy2
						firstP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 0.382)
						secondP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 0.5)
						thirdP = FCPoint.new(mpx2, mpy2 - (mpy2 - mpy1) * 0.618)
						startP = FCPoint.new(mpx1, mpy1)
						listP = []
						listP.push(firstP)
						listP.push(secondP)
						listP.push(thirdP)
						listSize = listP.length
						for j in 0..listSize - 1
							lineXY(chart, startP.x, startP.y, listP[j].x, listP[j].y, 0, 0)
							newX = 0
							newY = 0
							if mpx2 > mpx1
								newY = chart.kChart * (chart.size.cx - chart.rightVScaleWidth) + chart.bChart
								newX = (chart.size.cx - chart.rightVScaleWidth)
							else
								newY = chart.bChart
								newX = chart.leftVScaleWidth
							end
							chart.startMovePlot = selectSegment(chart, mp, startP.x, startP.y, newX, newY)
							if chart.startMovePlot
								break
							end
						end
					end
				end
			elsif plot.plotType == "FiboTimezone"
				fValue = 1
				aIndex = index1
				pos = 1
				divHeight = getCandleDivHeight(chart)
				chart.startMovePlot = selectSegment(chart, mp, mpx1, 0, mpx1, divHeight)
				if chart.startMovePlot == false
					while aIndex + fValue <= chart.lastVisibleIndex
						fValue = fibonacciValue(pos)
						newIndex = aIndex + fValue
						newX = getChartX(chart, newIndex)
						chart.startMovePlot = selectSegment(chart, mp, newX, 0, newX, divHeight)
						if chart.startMovePlot
							break
						end
						pos = pos + 1
					end
				end
			elsif plot.plotType == "Percent"
				listValue = getPercentParams(mpy1, mpy2)
				for j in 0..listValue.length - 1
					chart.startMovePlot = selectSegment(chart, mp, chart.leftVScaleWidth, listValue[j], chart.size.cx - chart.rightVScaleWidth, listValue[j])
					if chart.startMovePlot
						break
					end
				end
			end
			if chart.startMovePlot
				sPlot = plot
				plot.startKey1 = plot.key1
				plot.startValue1 = plot.value1
				plot.startKey2 = plot.key2
				plot.startValue2 = plot.value2
				plot.startKey3 = plot.key3
				plot.startValue3 = plot.value3
				break
			end
		end
	end
	return sPlot
end

#添加画线
#chart: 图表
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
def addPlotDefault(chart, firstTouch, firstPoint, secondTouch, secondPoint)
	mp = firstPoint
	if mp.y < getCandleDivHeight(chart)
		touchIndex = getChartIndex(chart, mp)
		if touchIndex >= chart.firstVisibleIndex && touchIndex <= chart.lastVisibleIndex
			if chart.addingPlot == "FiboTimezone"
				fIndex = touchIndex
				fDate = getChartDateByIndex(chart, fIndex)
				y = getCandleDivValue(chart, mp)
				newPlot = FCPlot.new()
				if chart.paint.defaultUIStyle == "light"
					newPlot.lineColor = "rgb(0,0,0)"
					newPlot.pointColor = "rgba(0,0,0,125)"
				elsif chart.paint.defaultUIStyle == "dark"
					newPlot.lineColor = "rgb(255,255,255)"
					newPlot.pointColor = "rgba(255,255,255,125)"
				end
				newPlot.key1 = fDate
				newPlot.value1 = y
				newPlot.plotType = chart.addingPlot
				chart.plots.push(newPlot)
				chart.sPlot = selectPlot(chart, mp)
			elsif chart.addingPlot == "Triangle" || chart.addingPlot == "CircumCycle" || chart.addingPlot == "ParalleGram" || chart.addingPlot == "AngleLine" || chart.addingPlot == "Parallel" || chart.addingPlot == "SymmetricTriangle"
				eIndex = touchIndex
				bIndex = eIndex - 5
				if bIndex >= 0
					fDate = getChartDateByIndex(chart, bIndex)
					sDate = getChartDateByIndex(chart, eIndex)
					y = getCandleDivValue(chart, mp)
					newPlot = FCPlot.new()
					if chart.paint.defaultUIStyle == "light"
						newPlot.lineColor = "rgb(0,0,0)"
						newPlot.pointColor = "rgba(0,0,0,125)"
					elsif chart.paint.defaultUIStyle == "dark"
						newPlot.lineColor = "rgb(255,255,255)"
						newPlot.pointColor = "rgba(255,255,255,125)"
					end
					newPlot.key1 = fDate
					newPlot.value1 = y
					newPlot.key2 = sDate
					newPlot.value2 = y
					newPlot.key3 = sDate
					newPlot.value3 = chart.candleMin + (chart.candleMax - chart.candleMin) / 2
					newPlot.plotType = chart.addingPlot
					chart.plots.push(newPlot)
					chart.sPlot = selectPlot(chart, mp)
				end
			else
				eIndex = touchIndex
				bIndex = eIndex - 5
				if bIndex >= 0
					fDate = getChartDateByIndex(chart, bIndex)
					sDate = getChartDateByIndex(chart, eIndex)
					y = getCandleDivValue(chart, mp)
					newPlot = FCPlot.new()
					if chart.paint.defaultUIStyle == "light"
						newPlot.lineColor = "rgb(0,0,0)"
						newPlot.pointColor = "rgba(0,0,0,125)"
					elsif chart.paint.defaultUIStyle == "dark"
						newPlot.lineColor = "rgb(255,255,255)"
						newPlot.pointColor = "rgba(255,255,255,125)"
					end
					newPlot.key1 = fDate
					newPlot.value1 = y
					newPlot.key2 = sDate
					newPlot.value2 = y
					newPlot.plotType = chart.addingPlot
					chart.plots.push(newPlot)
					chart.sPlot = selectPlot(chart, mp)
				end
			end
		end
	end
end

#图表的鼠标按下方法
#chart: 图表
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
def touchDownChart(chart, firstTouch, firstPoint, secondTouch, secondPoint)
	mp = firstPoint
	chart.selectShape = ""
	chart.selectShapeEx = ""
	chart.touchDownPointChart = mp
	chart.sPlot = selectPlot(chart, mp)
	if chart.sPlot == nil
		selectShape(chart, mp)
	end
	if chart.paint.isDoubleClick
		if chart.showCrossLine
			chart.showCrossLine = false
		else
			chart.showCrossLine = true
		end
	end
end

#图表的鼠标移动方法
#chart: 图表
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
def touchMoveChart(chart, firstTouch, firstPoint, secondTouch, secondPoint)
	if chart.data == nil || chart.data.length == 0
		return
	end
	mp = firstPoint
	chart.crossStopIndex = getChartIndex(chart, mp)
	chart.touchPosition = mp
	if firstTouch && chart.sPlot != nil
		newIndex = getChartIndex(chart, mp)
		if newIndex >= 0 && newIndex < chart.data.length
			newDate = getChartDateByIndex(chart, newIndex)
			newValue = getCandleDivValue(chart, mp)
			if chart.selectPlotPoint == 0
				chart.sPlot.key1 = newDate
				chart.sPlot.value1 = newValue
			elsif chart.selectPlotPoint == 1
				chart.sPlot.key2 = newDate
				chart.sPlot.value2 = newValue
			elsif chart.selectPlotPoint == 2
				chart.sPlot.key3 = newDate
				chart.sPlot.value3 = newValue
			elsif chart.startMovePlot
				bValue = getCandleDivValue(chart, chart.touchDownPointChart)
				bIndex = getChartIndex(chart, chart.touchDownPointChart)
				if chart.sPlot.key1 != nil
					chart.sPlot.value1 = chart.sPlot.startValue1 + (newValue - bValue)
					startIndex1 = getChartIndexByDate(chart, chart.sPlot.startKey1)
					newIndex1 = startIndex1 + (newIndex - bIndex)
					if newIndex1 < 0
						newIndex1 = 0
					elsif newIndex1 > chart.data.length - 1
						newIndex1 = chart.data.length - 1
					end
					chart.sPlot.key1 = getChartDateByIndex(chart, newIndex1)
				end
				if chart.sPlot.key2 != nil
					chart.sPlot.value2 = chart.sPlot.startValue2 + (newValue - bValue)
					startIndex2 = getChartIndexByDate(chart, chart.sPlot.startKey2)
					newIndex2 = startIndex2 + (newIndex - bIndex)
					if newIndex2 < 0
						newIndex2 = 0
					elsif newIndex2 > chart.data.length - 1
						newIndex2 = chart.data.length - 1
					end
					chart.sPlot.key2 = getChartDateByIndex(chart, newIndex2)
				end
				if chart.sPlot.key3 != nil
					chart.sPlot.value3 = chart.sPlot.startValue3 + (newValue - bValue)
					startIndex3 = getChartIndexByDate(chart, chart.sPlot.startKey3)
					newIndex3 = startIndex3 + (newIndex - bIndex)
					if newIndex3 < 0
						newIndex3 = 0
					elsif newIndex3 > chart.data.length - 1
						newIndex3 = chart.data.length - 1
					end
					chart.sPlot.key3 = getChartDateByIndex(chart, newIndex3)
				end
			end
		end
		return
	end
	if firstTouch && secondTouch
		if firstPoint.x > secondPoint.x
			chart.firstTouchPointCache = secondPoint
			chart.secondTouchPointCache = firstPoint
		else
			chart.firstTouchPointCache = firstPoint
			chart.secondTouchPointCache = secondPoint
		end
		if chart.firstTouchIndexCache == -1 || chart.secondTouchIndexCache == -1
			chart.firstTouchIndexCache = getChartIndex(chart, chart.firstTouchPointCache)
			chart.secondTouchIndexCache = getChartIndex(chart, chart.secondTouchPointCache)
			chart.firstIndexCache = chart.firstVisibleIndex
			chart.lastIndexCache = chart.lastVisibleIndex
		end
	elsif firstTouch
		chart.secondTouchIndexCache = -1
		if chart.firstTouchIndexCache == -1
			chart.firstTouchPointCache = firstPoint
			chart.firstTouchIndexCache = getChartIndex(chart, chart.firstTouchPointCache)
			chart.firstIndexCache = chart.firstVisibleIndex
			chart.lastIndexCache = chart.lastVisibleIndex
			chart.firstPaddingTop = chart.candlePaddingTop
			chart.firstPaddingBottom = chart.candlePaddingBottom
		end
	end

	if firstTouch && secondTouch
		if chart.firstTouchIndexCache != -1 && chart.secondTouchIndexCache != -1
			fPoint = firstPoint
			sPoint = secondPoint
			if firstPoint.x > secondPoint.x
				fPoint = secondPoint
				sPoint = firstPoint
			end
			subX = (sPoint.x - fPoint.x).abs
			subIndex = (chart.secondTouchIndexCache - chart.firstTouchIndexCache).abs
			if subX > 0 && subIndex > 0
				newScalePixel = subX / subIndex
				if newScalePixel >= 3
					intScalePixel = (newScalePixel).to_i
					newScalePixel = intScalePixel
				end
				if newScalePixel != chart.hScalePixel
					newFirstIndex = chart.firstTouchIndexCache
					thisX = fPoint.x
					thisX -= newScalePixel
					while thisX > chart.leftVScaleWidth + newScalePixel
						newFirstIndex = newFirstIndex - 1
						if newFirstIndex < 0
							newFirstIndex = 0
							break
						end
						thisX -= newScalePixel
					end
					thisX = sPoint.x
					newSecondIndex = chart.secondTouchIndexCache
					thisX += newScalePixel
					while thisX < chart.size.cx - chart.rightVScaleWidth - newScalePixel
						newSecondIndex = newSecondIndex + 1
						if newSecondIndex > chart.data.length - 1
							newSecondIndex = chart.data.length - 1
							break
						end
						thisX += newScalePixel
					end
					setChartVisibleIndex(chart, newFirstIndex, newSecondIndex)
					maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart))
					while (maxVisibleRecord < chart.lastVisibleIndex - chart.firstVisibleIndex + 1) and (chart.lastVisibleIndex > chart.firstVisibleIndex)
						chart.lastVisibleIndex = chart.lastVisibleIndex - 1
					end
					checkChartLastVisibleIndex(chart)
					resetChartVisibleRecord(chart)
					if chart.paint.onCalculateChartMaxMin != nil
						chart.paint.onCalculateChartMaxMin.call(chart)
					else
						calculateChartMaxMin(chart)
					end
				end
			end
		end
	elsif firstTouch
		subIndex = ((chart.firstTouchPointCache.x - firstPoint.x) / chart.hScalePixel).to_i
		if chart.lastVisibleIndex + subIndex > chart.data.length - 1
			subIndex = chart.data.length - 1 - chart.lastIndexCache
		elsif chart.firstVisibleIndex + subIndex < 0
			subIndex = -chart.firstIndexCache
		end
		if chart.allowDragChartDiv
			chart.candlePaddingTop = chart.firstPaddingTop - (chart.firstTouchPointCache.y - firstPoint.y).to_i
			chart.candlePaddingBottom = chart.firstPaddingBottom + (chart.firstTouchPointCache.y - firstPoint.y).to_i
		end
		chart.firstVisibleIndex = chart.firstIndexCache + subIndex
		chart.lastVisibleIndex = chart.lastIndexCache + subIndex
		checkChartLastVisibleIndex(chart)
		resetChartVisibleRecord(chart)
		if chart.paint.onCalculateChartMaxMin != nil
			chart.paint.onCalculateChartMaxMin.call(chart)
		else
			calculateChartMaxMin(chart)
		end
	end
end

#绘制刻度
#chart:图表
#paint:绘图对象
#clipRect:裁剪区域
def drawChartScale(chart, paint, clipRect)
	if chart.leftVScaleWidth > 0
		paint.fillRect(chart.scaleColor, chart.leftVScaleWidth, 0, chart.leftVScaleWidth + chart.lineWidthChart, chart.size.cy - chart.hScaleHeight)
	end
	if chart.rightVScaleWidth > 0
		paint.fillRect(chart.scaleColor, chart.size.cx - chart.rightVScaleWidth, 0, chart.size.cx - chart.rightVScaleWidth + chart.lineWidthChart, chart.size.cy - chart.hScaleHeight)
	end
	if chart.hScaleHeight > 0
		paint.fillRect(chart.scaleColor, 0, chart.size.cy - chart.hScaleHeight, chart.size.cx, chart.size.cy - chart.hScaleHeight + chart.lineWidthChart)
	end
	candleDivHeight = getCandleDivHeight(chart)
	volDivHeight = getVolDivHeight(chart)
	indDivHeight = getIndDivHeight(chart)
	indDivHeight2 = getIndDivHeight2(chart)
	if volDivHeight > 0
		paint.fillRect(chart.scaleColor, chart.leftVScaleWidth, candleDivHeight, chart.size.cx - chart.rightVScaleWidth, candleDivHeight + chart.lineWidthChart)
	end
	if indDivHeight > 0
		paint.fillRect(chart.scaleColor, chart.leftVScaleWidth, candleDivHeight + volDivHeight, chart.size.cx - chart.rightVScaleWidth, candleDivHeight + volDivHeight + chart.lineWidthChart)
	end
	if indDivHeight2 > 0
		paint.fillRect(chart.scaleColor, chart.leftVScaleWidth, candleDivHeight + volDivHeight + indDivHeight, chart.size.cx - chart.rightVScaleWidth, candleDivHeight + volDivHeight + indDivHeight + chart.lineWidthChart)
	end
	if chart.data != nil && chart.data.length > 0
		topPoint = FCPoint.new(0, 10)
		bottomPoint = FCPoint.new(0, candleDivHeight - 10)
		candleMax = getChartValue(chart, topPoint)
		candleMin = getChartValue(chart, bottomPoint)
		ret = chartGridScale(chart, candleMin, candleMax,  (candleDivHeight - chart.candlePaddingTop - chart.candlePaddingBottom) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, ((candleDivHeight - chart.candlePaddingTop - chart.candlePaddingBottom) / chart.vScaleDistance).to_i)
		if chart.gridStep > 0 && ret > 0
			drawValues = []
			isTrend = false
			if chart.cycle == "trend"
				isTrend = true
			end
			firstOpen = 0
			if isTrend
				firstOpen = chart.data[chart.firstVisibleIndex].close
				subValue = candleMax - candleMin
				count = ((candleDivHeight - chart.candlePaddingTop - chart.candlePaddingBottom) / chart.vScaleDistance).to_i
				if count > 0
					subValue /= count
				end
				start = firstOpen
				while start < candleMax
					start += subValue
					if start <= candleMax
						drawValues.push(start)
					end
				end
				start = firstOpen
				while start > candleMin
					start -= subValue
					if start >= candleMin
						drawValues.push(start)
					end
				end
			else
				start = 0
				if candleMin >= 0
					while start + chart.gridStep < candleMin
						start += chart.gridStep
					end
				else
					while start - chart.gridStep > candleMin
						start -= chart.gridStep
					end
				end

				while start <= candleMax
					if start > candleMin
						drawValues.push(start)
					end
					start += chart.gridStep
				end
			end
			drawValues.push(firstOpen)
			for i in 0..drawValues.length - 1
				start = drawValues[i]
				hAxisY = getChartY(chart, 0, start)
				if hAxisY < 1 || hAxisY > candleDivHeight
					next
				end
				paint.fillRect(chart.gridColor, chart.leftVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
				paint.fillRect(chart.scaleColor, chart.leftVScaleWidth - 8, hAxisY.to_i, chart.leftVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
				paint.fillRect(chart.scaleColor, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth + 8, hAxisY.to_i + chart.lineWidthChart)
				drawText = toFixed(start, chart.candleDigit)
				tSize = paint.textSize(drawText, chart.font)
				if isTrend
					diffRange = 100 * (start - firstOpen) / firstOpen
					diffRangeStr = toFixed(diffRange, 2) + "%"
					if diffRange >= 0
						paint.drawText(diffRangeStr, chart.upColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, hAxisY.to_i - tSize.cy / 2)
					else
						paint.drawText(diffRangeStr, chart.downColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, hAxisY.to_i - tSize.cy / 2)
					end
				else
					paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, hAxisY.to_i - tSize.cy / 2)
				end
				paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, hAxisY.to_i - tSize.cy / 2)
			end
		end
		topPoint = FCPoint.new(0, candleDivHeight + 10)
		bottomPoint = FCPoint.new(0, candleDivHeight + volDivHeight - 10)
		volMax = getChartValue(chart, topPoint)
		volMin = getChartValue(chart, bottomPoint)
		ret = chartGridScale(chart, volMin, volMax,  (volDivHeight - chart.volPaddingTop - chart.volPaddingBottom) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, ((volDivHeight - chart.volPaddingTop - chart.volPaddingBottom) / chart.vScaleDistance).to_i)
		if chart.gridStep > 0 && ret > 0
			start = 0
			if volMin >= 0
				while start + chart.gridStep < volMin
					start += chart.gridStep
				end
			else
				while start - chart.gridStep > volMin
					start -= chart.gridStep
				end
			end
			while start <= volMax
				if start > volMin
					hAxisY = getChartY(chart, 1, start)
					if hAxisY < candleDivHeight || hAxisY > candleDivHeight + volDivHeight
						next
					end
					paint.fillRect(chart.gridColor, chart.leftVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
					paint.fillRect(chart.scaleColor, chart.leftVScaleWidth - 8, hAxisY.to_i, chart.leftVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
					paint.fillRect(chart.scaleColor, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth + 8, hAxisY.to_i + chart.lineWidthChart)
					drawText = toFixed((start/chart.magnitude), chart.volDigit)
					tSize = paint.textSize(drawText, chart.font)
					paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, hAxisY.to_i - tSize.cy / 2)
					paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, hAxisY.to_i - tSize.cy / 2)
				end
				start += chart.gridStep
			end
		end
		if indDivHeight > 0
			topPoint = FCPoint.new(0, candleDivHeight + volDivHeight + 10)
			bottomPoint = FCPoint.new(0, candleDivHeight + volDivHeight + indDivHeight - 10)
			indMax = getChartValue(chart, topPoint)
			indMin = getChartValue(chart, bottomPoint)
			ret = chartGridScale(chart, indMin, indMax, (indDivHeight - chart.indPaddingTop - chart.indPaddingBottom) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, ((indDivHeight - chart.indPaddingTop - chart.indPaddingBottom) / chart.vScaleDistance).to_i)
			if chart.gridStep > 0 && ret > 0
				start = 0
				if indMin >= 0
					while start + chart.gridStep < indMin
						start += chart.gridStep
					end
				else
					while start - chart.gridStep > indMin
						start -= chart.gridStep
					end
				end
				while start <= indMax
					if start > indMin
						hAxisY = getChartY(chart, 2, start)
						if hAxisY < candleDivHeight + volDivHeight || hAxisY > candleDivHeight + volDivHeight + indDivHeight
							next
						end
						paint.fillRect(chart.gridColor, chart.leftVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
						paint.fillRect(chart.scaleColor, chart.leftVScaleWidth - 8, hAxisY.to_i, chart.leftVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
						paint.fillRect(chart.scaleColor, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth + 8, hAxisY.to_i + chart.lineWidthChart)
						drawText = toFixed(start, chart.indDigit)
						tSize = paint.textSize(drawText, chart.font)
						paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, hAxisY.to_i - tSize.cy / 2)
						paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, hAxisY.to_i - tSize.cy / 2)
					end
					start += chart.gridStep
				end
			end
		end
		if indDivHeight2 > 0
			topPoint = FCPoint.new(0, candleDivHeight + volDivHeight + indDivHeight + 10)
			bottomPoint = FCPoint.new(0, candleDivHeight + volDivHeight + indDivHeight + indDivHeight2 - 10)
			indMax2 = getChartValue(chart, topPoint)
			indMin2 = getChartValue(chart, bottomPoint)
			ret = chartGridScale(chart, indMin2, indMax2, (indDivHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) / 2, chart.vScaleDistance, chart.vScaleDistance / 2, ((indDivHeight2 - chart.indPaddingTop2 - chart.indPaddingBottom2) / chart.vScaleDistance).to_i)
			if chart.gridStep > 0 && ret > 0
				start = 0
				if indMin2 >= 0
					while start + chart.gridStep < indMin2
						start += chart.gridStep
					end
				else
					while start - chart.gridStep > indMin2
						start -= chart.gridStep 
					end
				end
				while start <= indMax2
					if start > indMin2
						hAxisY = getChartY(chart, 3, start)
						if hAxisY < candleDivHeight + volDivHeight + indDivHeight || hAxisY > candleDivHeight + volDivHeight + indDivHeight + indDivHeight2
							next
						end
						paint.fillRect(chart.gridColor, chart.leftVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
						paint.fillRect(chart.scaleColor, chart.leftVScaleWidth - 8, hAxisY.to_i, chart.leftVScaleWidth, hAxisY.to_i + chart.lineWidthChart)
						paint.fillRect(chart.scaleColor, chart.size.cx - chart.rightVScaleWidth, hAxisY.to_i, chart.size.cx - chart.rightVScaleWidth + 8, hAxisY.to_i + chart.lineWidthChart)
						drawText = toFixed(start, chart.indDigit)
						tSize = paint.textSize(drawText, chart.font)
						paint.drawText(drawText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth + 10, hAxisY.to_i - tSize.cy / 2)
						paint.drawText(drawText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx - 10, hAxisY.to_i - tSize.cy / 2)
					end
					start += chart.gridStep
				end
			end
		end
		if paint.onPaintChartHScale != nil
			paint.onPaintChartHScale.call(chart, paint, clipRect)
		else
			if chart.data != nil && chart.data.length > 0 && chart.hScaleHeight > 0
				dLeft = chart.leftVScaleWidth + 10
				i = chart.firstVisibleIndex
				while i <= chart.lastVisibleIndex
					xText = ""
					if chart.hScaleFormat.length > 0
						xText = Time.at(chart.data[i].date).strftime(chart.hScaleFormat)
					else
						if chart.cycle == "day"
							xText = Time.at(chart.data[i].date).strftime("%Y-%m-%d")
						elsif chart.cycle == "minute"
							xText = Time.at(chart.data[i].date).strftime("%Y-%m-%d %H:%M")
						elsif chart.cycle == "trend"
							xText = Time.at(chart.data[i].date).strftime("%H:%MM")
						elsif chart.cycle == "second"
							xText = Time.at(chart.data[i].date).strftime("%H:%M:%S")
						elsif chart.cycle == "tick"
							xText = (i + 1).to_s
						end
					end
					tSize = paint.textSize(xText, chart.font)
					x = getChartX(chart, i)
					dx = x - tSize.cx / 2
					if dx > dLeft && dx < chart.size.cx - chart.rightVScaleWidth - 10
						paint.drawLine(chart.scaleColor, chart.lineWidthChart, 0, x, chart.size.cy - chart.hScaleHeight, x, chart.size.cy - chart.hScaleHeight + 8)
						paint.drawText(xText, chart.textColor, chart.font, dx, chart.size.cy - chart.hScaleHeight + 8  - tSize.cy / 2 + 7)
						i = i + ((tSize.cx + chart.hScaleTextDistance) / chart.hScalePixel).to_i + 1
					else
						i = i + 1
					end
				end
			end
		end
	end
end

#绘制十字线
#chart:图表
#paint:绘图对象
#clipRect:裁剪区域
def drawChartCrossLine(chart, paint, clipRect)
	if chart.data == nil || chart.data.length == 0
		return
	end
	candleDivHeight = getCandleDivHeight(chart)
	volDivHeight = getVolDivHeight(chart)
	indDivHeight = getIndDivHeight(chart)
	indDivHeight2 = getIndDivHeight2(chart)
	crossLineIndex = chart.crossStopIndex
	if crossLineIndex == -1 || chart.showCrossLine == false
		crossLineIndex = chart.lastVisibleIndex
	end
	if volDivHeight > 0
		drawTitles = []
		drawColors = []
		if chart.data.length > 0
			drawTitles.push("VOL " + toFixed(chart.data[crossLineIndex].volume, chart.volDigit))
			drawColors.push(chart.textColor)
		else
			drawTitles.push("VOL")
			drawColors.push(chart.textColor)
		end
		if chart.shapes.length > 0
			for i in 0..chart.shapes.length - 1
				shape = chart.shapes[i]
				if shape.divIndex == 1
					if shape.title.length > 0
						if shape.shapeType == "bar"  && shape.style == "2color"
							drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit))
							drawColors.push(shape.color2)
						else
							if shape.shapeType != "text"
								drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit))
								drawColors.push(shape.color)
								if shape.datas2.length > 0
									drawTitles.push(shape.title2 + " " + toFixed(shape.datas2[crossLineIndex], chart.indDigit))
									drawColors.push(shape.color2)
								end
							end
						end
					end
				end
			end
		end		
		iLeft = chart.leftVScaleWidth + 5
		for i in 0..drawTitles.length - 1
			tSize = paint.textSize(drawTitles[i], chart.font)
			paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, candleDivHeight + 5)
			iLeft += tSize.cx + 5
		end
	end
	if chart.cycle == "trend"
		drawTitles = []
		drawColors = []
		if chart.data.length > 0
			drawTitles.push("CLOSE" + toFixed(chart.data[crossLineIndex].close, chart.candleDigit))
			drawColors.push(chart.textColor)
		else
			drawTitles.push("CLOSE")
			drawColors.push(chart.textColor)
		end
		iLeft = chart.leftVScaleWidth + 5
		if chart.shapes.length > 0
			for i in 0..chart.shapes.length - 1
				shape = chart.shapes[i]
				if shape.divIndex == 0
					if shape.title.length > 0
						if shape.shapeType == "bar"  && shape.style == "2color"
							drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit))
							drawColors.push(shape.color2)
						else
							if shape.shapeType != "text"
								drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit))
								drawColors.push(shape.color)
								if shape.datas2.length > 0
									drawTitles.push(shape.title2 + " " + toFixed(shape.datas2[crossLineIndex], chart.indDigit))
									drawColors.push(shape.color2)
								end
							end
						end
					end
				end
			end
		end
		for i in 0..drawTitles.length - 1
			tSize = paint.textSize(drawTitles[i], chart.font)
			paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, 5)
			iLeft += tSize.cx + 5
		end
	else
		drawTitles = []
		drawColors = []
		if chart.mainIndicator == "MA"
			if chart.ma5.length > 0
				drawTitles.push("MA5 " + toFixed(chart.ma5[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("MA5")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.ma10.length > 0
				drawTitles.push("MA10 " + toFixed(chart.ma10[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("MA10")
			end
			drawColors.push(chart.indicatorColors[1])
			if chart.ma20.length > 0
				drawTitles.push("MA20 " + toFixed(chart.ma20[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("MA20")
			end
			drawColors.push(chart.indicatorColors[2])
			if chart.ma30.length > 0
				drawTitles.push("MA30 " + toFixed(chart.ma30[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("MA30")
			end
			drawColors.push(chart.indicatorColors[5])
			if chart.ma120.length > 0
				drawTitles.push("MA120 " + toFixed(chart.ma120[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("MA120")
			end
			drawColors.push(chart.indicatorColors[4])
			if chart.ma250.length > 0
				drawTitles.push("MA250 " + toFixed(chart.ma250[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("MA250")
			end
			drawColors.push(chart.indicatorColors[3])
		elsif chart.mainIndicator == "BOLL"
			if chart.boll_mid.length > 0
				drawTitles.push("MID " + toFixed(chart.boll_mid[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("MID")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.boll_up.length > 0
				drawTitles.push("UP " + toFixed(chart.boll_up[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("UP")
			end
			drawColors.push(chart.indicatorColors[1])
			if(chart.boll_down.length > 0)
				drawTitles.push("LOW " + toFixed(chart.boll_down[crossLineIndex], chart.candleDigit))
			else
				drawTitles.push("LOW")
			end
			drawColors.push(chart.indicatorColors[2])
		end
		if chart.shapes.length > 0
			for i in 0..chart.shapes.length - 1
				shape = chart.shapes[i]
				if shape.divIndex == 0
					if shape.title.length > 0
						if shape.shapeType == "bar" && shape.style == "2color"
							drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.candleDigit))
							drawColors.push(shape.color2)
						else
							if shape.shapeType != "text"
								drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.candleDigit))
								drawColors.push(shape.color)
								if shape.datas2.length > 0
									drawTitles.push(shape.title2 + " " + toFixed(shape.datas2[crossLineIndex], chart.candleDigit))
									drawColors.push(shape.color2)
								end
							end
						end
					end
				end
			end
		end
		iLeft = chart.leftVScaleWidth + 5
		for i in 0..drawTitles.length - 1
			tSize = paint.textSize(drawTitles[i], chart.font)
			paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, 5)
			iLeft += tSize.cx + 5
		end
	end
	if indDivHeight > 0
		drawTitles = []
		drawColors = []
		if chart.showIndicator == "MACD"
			if chart.alldifarr.length > 0
				drawTitles.push("DIF " + toFixed(chart.alldifarr[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("DIF")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.alldeaarr.length > 0
				drawTitles.push("DEA " + toFixed(chart.alldeaarr[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("DEA")
			end
			drawColors.push(chart.indicatorColors[1])
			if chart.allmacdarr.length > 0
				drawTitles.push("MACD " + toFixed(chart.allmacdarr[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("MACD")
			end
			drawColors.push(chart.indicatorColors[4])
		elsif chart.showIndicator == "KDJ"
			if chart.kdj_k.length > 0
				drawTitles.push("K " + toFixed(chart.kdj_k[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("K")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.kdj_d.length > 0
				drawTitles.push("D " + toFixed(chart.kdj_d[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("D")
			end
			drawColors.push(chart.indicatorColors[1])
			if chart.kdj_j.length > 0
				drawTitles.push("J " + toFixed(chart.kdj_j[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("J")
			end
			drawColors.push(chart.indicatorColors[2])
		elsif chart.showIndicator == "RSI"
			if chart.rsi1.length > 0
				drawTitles.push("RSI6 " + toFixed(chart.rsi1[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("RSI6")
			end
			drawColors.push(chart.indicatorColors[5])
			if chart.rsi2.length > 0
				drawTitles.push("RSI12 " + toFixed(chart.rsi2[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("RSI12")
			end
			drawColors.push(chart.indicatorColors[1])
			if chart.rsi3.length > 0
				drawTitles.push("RSI24 " + toFixed(chart.rsi3[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("RSI24")
			end
			drawColors.push(chart.indicatorColors[2])
		elsif chart.showIndicator == "BIAS"
			if chart.bias1.length > 0
				drawTitles.push("BIAS6 " + toFixed(chart.bias1[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("BIAS6")
			end
			drawColors.push(chart.indicatorColors[5])
			if chart.bias2.length > 0
				drawTitles.push("BIAS12 " + toFixed(chart.bias2[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("BIAS12")
			end
			drawColors.push(chart.indicatorColors[1])
			if chart.bias3.length > 0
				drawTitles.push("BIAS24 " + toFixed(chart.bias3[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("BIAS24")
			end
			drawColors.push(chart.indicatorColors[2])
		elsif chart.showIndicator == "ROC"
			if chart.roc.length > 0
				drawTitles.push("ROC " + toFixed(chart.roc[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("ROC")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.roc_ma.length > 0
				drawTitles.push("ROCMA " + toFixed(chart.roc_ma[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("ROCMA")
			end
			drawColors.push(chart.indicatorColors[1])       
		elsif chart.showIndicator == "WR"
			if chart.wr1.length > 0
				drawTitles.push("WR5 " + toFixed(chart.wr1[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("WR5")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.wr2.length > 0
				drawTitles.push("WR10 " + toFixed(chart.wr2[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("WR10")
			end
			drawColors.push(chart.indicatorColors[1])
		elsif chart.showIndicator == "CCI"
			if chart.cci.length > 0
				drawTitles.push("CCI " + toFixed(chart.cci[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("CCI")
			end
			drawColors.push(chart.indicatorColors[0])
		elsif chart.showIndicator == "BBI"
			if chart.bbi.length > 0
				drawTitles.push("BBI " + toFixed(chart.bbi[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("BBI")
			end
			drawColors.push(chart.indicatorColors[0])
		elsif chart.showIndicator == "TRIX"
			if chart.trix.length > 0
				drawTitles.push("TRIX " + toFixed(chart.trix[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("TRIX")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.trix_ma.length > 0
				drawTitles.push("TRIXMA " + toFixed(chart.trix_ma[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("TRIXMA")
			end
			drawColors.push(chart.indicatorColors[1])
		elsif chart.showIndicator == "DMA"
			if chart.dma1.length > 0
				drawTitles.push("MA10 " + toFixed(chart.dma1[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("MA10")
			end
			drawColors.push(chart.indicatorColors[0])
			if chart.dma2.length > 0
				drawTitles.push("MA50 " + toFixed(chart.dma2[crossLineIndex], chart.indDigit))
			else
				drawTitles.push("MA50")
			end
			drawColors.push(chart.indicatorColors[1])
		end
		if chart.shapes.length > 0
			for i in 0..chart.shapes.length - 1
				shape = chart.shapes[i]
				if shape.divIndex == 2
					if shape.title.length > 0
						if shape.shapeType == "bar"  && shape.style == "2color"
							drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit))
							drawColors.push(shape.color2)
						else
							if shape.shapeType != "text"
								drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit))
								drawColors.push(shape.color)
								if shape.datas2.length > 0
									drawTitles.push(shape.title2 + " " + toFixed(shape.datas2[crossLineIndex], chart.indDigit))
									drawColors.push(shape.color2)
								end
							end
						end
					end
				end
			end
		end
		iLeft = chart.leftVScaleWidth + 5
		for i in 0..drawTitles.length - 1
			tSize = paint.textSize(drawTitles[i], chart.font)
			paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, candleDivHeight + volDivHeight + 5)
			iLeft += tSize.cx + 5
		end
	end
	if indDivHeight2 > 0
		drawTitles = []
		drawColors = []
		if chart.shapes.length > 0
			for i in 0..chart.shapes.length - 1
				shape = chart.shapes[i]
				if shape.divIndex == 3
					if shape.title.length > 0
						if shape.shapeType == "bar"  && shape.style == "2color"
							drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit2))
							drawColors.push(shape.color2)
						else
							if shape.shapeType != "text"
								drawTitles.push(shape.title + " " + toFixed(shape.datas[crossLineIndex], chart.indDigit2))
								drawColors.push(shape.color)
								if shape.datas2.length > 0
									drawTitles.push(shape.title2 + " " + toFixed(shape.datas2[crossLineIndex], chart.indDigit2))
									drawColors.push(shape.color2)
								end
							end
						end
					end
				end
			end
			if drawTitles.length > 0
				iLeft = chart.leftVScaleWidth + 5
				for i in 0..drawTitles.length - 1
					tSize = paint.textSize(drawTitles[i], chart.font)
					paint.drawText(drawTitles[i], drawColors[i], chart.font, iLeft, candleDivHeight + volDivHeight + indDivHeight + 5)
					iLeft += tSize.cx + 5
				end
			end
		end
	end
	if chart.showCrossLine
		rightText = ""
		if chart.touchPosition.y < candleDivHeight
			rightText = toFixed(getChartValue(chart, chart.touchPosition), chart.candleDigit)	
		elsif chart.touchPosition.y > candleDivHeight && chart.touchPosition.y < candleDivHeight + volDivHeight
			rightText = toFixed(getChartValue(chart, chart.touchPosition), chart.volDigit)
		elsif chart.touchPosition.y > candleDivHeight + volDivHeight && chart.touchPosition.y < candleDivHeight + volDivHeight + indDivHeight
			rightText = toFixed(getChartValue(chart, chart.touchPosition), chart.indDigit)
		elsif chart.touchPosition.y > candleDivHeight + volDivHeight + indDivHeight && chart.touchPosition.y < candleDivHeight + volDivHeight + indDivHeight + indDivHeight2
			rightText = toFixed(getChartValue(chart, chart.touchPosition), chart.indDigit2)
		end
		drawY = chart.touchPosition.y
		if drawY > chart.size.cy - chart.hScaleHeight
			drawY = chart.size.cy - chart.hScaleHeight
		end
		tSize = paint.textSize(rightText, chart.font)
		if chart.leftVScaleWidth > 0
			paint.fillRect(chart.crossTipColor, chart.leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2 - 4, chart.leftVScaleWidth, drawY + tSize.cy / 2 + 3)
			paint.drawText(rightText, chart.textColor, chart.font, chart.leftVScaleWidth - tSize.cx, drawY - tSize.cy / 2)
		end
		if chart.rightVScaleWidth > 0
			paint.fillRect(chart.crossTipColor, chart.size.cx - chart.rightVScaleWidth, drawY - tSize.cy / 2 - 4, chart.size.cx - chart.rightVScaleWidth + tSize.cx, drawY + tSize.cy / 2 + 3)
			paint.drawText(rightText, chart.textColor, chart.font, chart.size.cx - chart.rightVScaleWidth, drawY - tSize.cy / 2)
		end
		drawX = chart.touchPosition.x
		if drawX < chart.leftVScaleWidth
			drawX = chart.leftVScaleWidth
		end
		if drawX > chart.size.cx - chart.rightVScaleWidth
			drawX = chart.size.cx - chart.rightVScaleWidth
		end
		if chart.sPlot == nil && chart.selectShape == ""
			paint.fillRect(chart.crossLineColor, chart.leftVScaleWidth, drawY, chart.size.cx - chart.rightVScaleWidth, drawY + chart.lineWidthChart)
			paint.fillRect(chart.crossLineColor, drawX, 0, drawX + chart.lineWidthChart, chart.size.cy - chart.hScaleHeight)
		end
		if chart.crossStopIndex != -1
			xText = ""
			if chart.cycle == "day"
				xText = Time.at(chart.data[chart.crossStopIndex].date).strftime("%Y-%m-%d")
			elsif chart.cycle == "minute"
				xText = Time.at(chart.data[chart.crossStopIndex].date).strftime("%Y-%m-%d %H:%M")
			elsif chart.cycle == "trend"
				xText = Time.at(chart.data[chart.crossStopIndex].date).strftime("%H:%MM")
			elsif chart.cycle == "second"
				xText = Time.at(chart.data[chart.crossStopIndex].date).strftime("%H:%M:%S")
			elsif chart.cycle == "tick"
				xText = (chart.crossStopIndex + 1).to_s
			end
			if chart.hScaleFormat.length > 0
				xText = Time.at(chart.data[chart.crossStopIndex].date).strftime(chart.hScaleFormat)
			end
			xSize = paint.textSize(xText, chart.font)
			paint.fillRect(chart.crossTipColor, drawX - xSize.cx / 2 - 2, candleDivHeight + volDivHeight + indDivHeight, drawX + xSize.cx / 2 + 2, candleDivHeight + volDivHeight + indDivHeight + xSize.cy + 6)
			paint.drawText(xText, chart.textColor, chart.font, drawX - xSize.cx / 2, candleDivHeight + volDivHeight + indDivHeight + 3)
		end
	end
end

#绘制图表
#chart:图表
#paint:绘图对象
#clipRect:裁剪区域
def drawChartStock(chart, paint, clipRect)
	if chart.data != nil && chart.data.length > 0
		candleHeight = getCandleDivHeight(chart)
		volHeight = getVolDivHeight(chart)
		indHeight = getIndDivHeight(chart)
		isTrend = false
		if chart.cycle == "trend"
			isTrend = true
		end
		cWidth = ((chart.hScalePixel - 3) / 2).to_i
		if cWidth < 0
			cWidth = 0
		end
		lastValidIndex = chart.lastVisibleIndex
		if chart.lastValidIndex != -1
			lastValidIndex = chart.lastValidIndex
		end
		maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart))
		newPaint = nil
		newPaint = paint
		divHeight = getCandleDivHeight(chart)
		newPaint.setClip(chart.leftVScaleWidth, 0, chart.size.cx, divHeight)
		if isTrend
			drawPoints = []
			for i in chart.firstVisibleIndex..lastValidIndex
				x = getChartX(chart, i)
				close = chart.data[i].close
				closeY = getChartY(chart, 0, close)
				drawPoints.push(FCPoint.new(x, closeY))
			end
			newPaint.drawPolyline(chart.indicatorColors[7], chart.lineWidthChart, 0, drawPoints)
		end
		hasMinTag = false
		hasMaxTag = false
		for i in chart.firstVisibleIndex..lastValidIndex
			x = getChartX(chart, i)
			openValue = chart.data[i].open
			close = chart.data[i].close
			high = chart.data[i].high
			low = chart.data[i].low
			openY = getChartY(chart, 0, openValue)
			closeY = getChartY(chart, 0, close)
			highY = getChartY(chart, 0, high)
			lowY = getChartY(chart, 0, low)
			if close >= openValue
				if isTrend == false
					newPaint.fillRect(chart.upColor, x, highY, x + chart.lineWidthChart, lowY)
					if cWidth > 0
						if close == openValue
							newPaint.fillRect(chart.upColor, x - cWidth, closeY, x + cWidth, closeY + chart.lineWidthChart)
						else
							newPaint.fillRect(chart.upColor, x - cWidth, closeY, x + cWidth + 1, openY)
						end
					end
				end
			else
				if isTrend == false
					newPaint.fillRect(chart.downColor, x, highY, x + chart.lineWidthChart, lowY)
					if cWidth > 0
						newPaint.fillRect(chart.downColor, x - cWidth, openY, x + cWidth + 1, closeY)
					end
				end
			end
			if chart.selectShape == "CANDLE"
				kPInterval = (maxVisibleRecord / 30).to_i
				if kPInterval < 2
					kPInterval = 3
				end
				if i % kPInterval == 0
					if isTrend == false
						newPaint.fillRect(chart.indicatorColors[0], x - 3, closeY - 3, x + 3, closeY + 3)
					end
				end
			end
			if isTrend == false
				if hasMaxTag == false
					if high == chart.candleMax
						tag = toFixed(high, chart.candleDigit)
						tSize = newPaint.textSize(tag, chart.font)
						newPaint.drawText(tag, chart.textColor, chart.font, x - tSize.cx / 2, highY - tSize.cy - 2)
						hasMaxTag = true
					end
				end
				if hasMinTag == false
					if low == chart.candleMin
						tag = toFixed(low, chart.candleDigit)
						tSize = newPaint.textSize(tag, chart.font)
						newPaint.drawText(tag, chart.textColor, chart.font, x - tSize.cx / 2, lowY + 2)
						hasMinTag = true
					end
				end
			end
		end
		newPaint.setClip(0, 0, chart.size.cx, chart.size.cy)
		for i in chart.firstVisibleIndex..lastValidIndex
			x = getChartX(chart, i)
			openValue = chart.data[i].open
			close = chart.data[i].close
			openY = getChartY(chart, 0, openValue)
			closeY = getChartY(chart, 0, close)
			volY = 0
			zeroY = 0
			if volHeight > 0
				volume = chart.data[i].volume
				volY = getChartY(chart, 1, volume)
				zeroY = getChartY(chart, 1, 0) 
			end
			if close >= openValue
				if isTrend
					if volHeight > 0
						paint.fillRect(chart.indicatorColors[6], x, volY, x + chart.lineWidthChart, zeroY)
					end
				else
					if cWidth > 0
						if volHeight > 0
							paint.fillRect(chart.upColor, x - cWidth, volY, x + cWidth + 1, zeroY)
						end
					else
						if volHeight > 0
							paint.drawLine(chart.upColor, chart.lineWidthChart, 0, x - cWidth, volY, x + cWidth, zeroY)
						end
					end
				end
			else
				if isTrend
					if volHeight > 0
						paint.fillRect(chart.indicatorColors[6], x, volY, x + chart.lineWidthChart, zeroY)
					end
				else
					if cWidth > 0
						if volHeight > 0
							paint.fillRect(chart.downColor, x - cWidth, volY, x + cWidth + 1, zeroY)
						end
					else
						if volHeight > 0
							paint.drawLine(chart.downColor, chart.lineWidthChart, 0, x - cWidth, volY, x + cWidth, zeroY)
						end
					end
				end
			end
			if chart.selectShape == "VOL"
				kPInterval = (maxVisibleRecord / 30).to_i
				if kPInterval < 2
					kPInterval = 3
				end
				if i % kPInterval == 0
					paint.fillRect(chart.indicatorColors[0], x - 3, volY - 3, x + 3, volY + 3)
				end
			end
		end
		if isTrend == false
			newPaint = nil
			newPaint = paint
			divHeight = getCandleDivHeight(chart)
			newPaint.setClip(chart.leftVScaleWidth, 0, chart.size.cx, divHeight)
			if chart.mainIndicator == "BOLL"
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "MID"
					drawChartLines(chart, newPaint, clipRect, 0, chart.boll_mid, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.boll_mid, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "UP"
					drawChartLines(chart, newPaint, clipRect, 0, chart.boll_up, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.boll_up, chart.indicatorColors[1], false)
				end
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "DOWN"
					drawChartLines(chart, newPaint, clipRect, 0, chart.boll_down, chart.indicatorColors[2], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.boll_down, chart.indicatorColors[2], false)
				end
			elsif chart.mainIndicator == "MA"
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "5"
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma5, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma5, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "10"
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma10, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma10, chart.indicatorColors[1], false)
				end
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "20"
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma20, chart.indicatorColors[2], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma20, chart.indicatorColors[2], false)
				end
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "30"
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma30, chart.indicatorColors[3], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma30, chart.indicatorColors[3], false)
				end
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "120"
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma120, chart.indicatorColors[4], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma120, chart.indicatorColors[4], false)
				end
				if chart.selectShape == chart.mainIndicator && chart.selectShapeEx == "250"
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma250, chart.indicatorColors[5], true)
				else
					drawChartLines(chart, newPaint, clipRect, 0, chart.ma250, chart.indicatorColors[5], false)
				end
			end
			newPaint.setClip(0, 0, chart.size.cx, chart.size.cy)
		end
		if indHeight > 0
			if chart.showIndicator == "MACD"
				zeroY = getChartY(chart, 2, 0)
				paint.fillRect(chart.indicatorColors[4], chart.leftVScaleWidth, zeroY, getChartX(chart, chart.lastVisibleIndex), zeroY + chart.lineWidthChart)
				for i in chart.firstVisibleIndex..lastValidIndex
					x = getChartX(chart, i)
					macd = chart.allmacdarr[i]
					macdY = getChartY(chart, 2, macd)
					if macdY < zeroY
						paint.fillRect(chart.indicatorColors[3], x, macdY, x + chart.lineWidthChart, zeroY)
					else
						paint.fillRect(chart.indicatorColors[4], x, zeroY, x + chart.lineWidthChart, macdY)
					end
					if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "MACD"
						kPInterval = (maxVisibleRecord / 30).to_i
						if kPInterval < 2
							kPInterval = 3
						end
						if i % kPInterval == 0
							paint.fillRect(chart.indicatorColors[4], x - 3, macdY - 3, x + 3, macdY + 3)
						end
					end
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "DIF"
					drawChartLines(chart, paint, clipRect, 2, chart.alldifarr, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.alldifarr, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "DEA"
					drawChartLines(chart, paint, clipRect, 2, chart.alldeaarr, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.alldeaarr, chart.indicatorColors[1], false)
				end
			elsif chart.showIndicator == "KDJ"
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "K"
					drawChartLines(chart, paint, clipRect, 2, chart.kdj_k, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.kdj_k, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "D"
					drawChartLines(chart, paint, clipRect, 2, chart.kdj_d, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.kdj_d, chart.indicatorColors[1], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "J"
					drawChartLines(chart, paint, clipRect, 2, chart.kdj_j, chart.indicatorColors[2], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.kdj_j, chart.indicatorColors[2], false)
				end
			elsif chart.showIndicator == "RSI"
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "6"
					drawChartLines(chart, paint, clipRect, 2, chart.rsi1, chart.indicatorColors[5], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.rsi1, chart.indicatorColors[5], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "12"
					drawChartLines(chart, paint, clipRect, 2, chart.rsi2, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.rsi2, chart.indicatorColors[1], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "24"
					drawChartLines(chart, paint, clipRect, 2, chart.rsi3, chart.indicatorColors[2], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.rsi3, chart.indicatorColors[2], false)
				end
			elsif chart.showIndicator == "BIAS"
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "1"
					drawChartLines(chart, paint, clipRect, 2, chart.bias1, chart.indicatorColors[5], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.bias1, chart.indicatorColors[5], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "2"
					drawChartLines(chart, paint, clipRect, 2, chart.bias2, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.bias2, chart.indicatorColors[1], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "3"
					drawChartLines(chart, paint, clipRect, 2, chart.bias3, chart.indicatorColors[2], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.bias3, chart.indicatorColors[2], false)
				end
			elsif chart.showIndicator == "ROC"
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "ROC"
					drawChartLines(chart, paint, clipRect, 2, chart.roc, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.roc, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "ROCMA"
					drawChartLines(chart, paint, clipRect, 2, chart.roc_ma, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.roc_ma, chart.indicatorColors[1], false)
				end
			elsif chart.showIndicator == "WR"
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "1"
					drawChartLines(chart, paint, clipRect, 2, chart.wr1, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.wr1, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "2"
					drawChartLines(chart, paint, clipRect, 2, chart.wr2, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.wr2, chart.indicatorColors[1], false)
				end
			elsif chart.showIndicator == "CCI"
				if chart.selectShape == chart.showIndicator
					drawChartLines(chart, paint, clipRect, 2, chart.cci, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.cci, chart.indicatorColors[0], false)
				end
			elsif chart.showIndicator == "BBI"
				if chart.selectShape == chart.showIndicator
					drawChartLines(chart, paint, clipRect, 2, chart.bbi, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.bbi, chart.indicatorColors[0], false)
				end
			elsif chart.showIndicator == "TRIX"
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "TRIX"
					drawChartLines(chart, paint, clipRect, 2, chart.trix, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.trix, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "TRIXMA"
					drawChartLines(chart, paint, clipRect, 2, chart.trix_ma, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.trix_ma, chart.indicatorColors[1], false)
				end
			elsif chart.showIndicator == "DMA"
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "DIF"
					drawChartLines(chart, paint, clipRect, 2, chart.dma1, chart.indicatorColors[0], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.dma1, chart.indicatorColors[0], false)
				end
				if chart.selectShape == chart.showIndicator && chart.selectShapeEx == "DIFMA"
					drawChartLines(chart, paint, clipRect, 2, chart.dma2, chart.indicatorColors[1], true)
				else
					drawChartLines(chart, paint, clipRect, 2, chart.dma2, chart.indicatorColors[1], false)
				end
			end
		end
	end
	#绘制扩展线条
	if chart.shapes.length > 0
		for i in 0..chart.shapes.length - 1
			shape = chart.shapes[i]
			if shape.shapeType == "bar"
				for j in chart.firstVisibleIndex..lastValidIndex
					if shape.showHideDatas.length > j && (shape.showHideDatas[j]).to_s == "0"
						next
					end
					x = getChartX(chart, j)
					y1 = 0
					if shape.leftOrRight
						y1 = getChartY(chart, shape.divIndex, shape.datas[j])
					else
						y1 = getChartYInRight(chart, shape.divIndex, shape.datas[j])
					end
					if shape.style != "2color"
						y2 = 0
						if shape.leftOrRight
							y2 = getChartY(chart, shape.divIndex, shape.datas2[j])
						else
							y2 = getChartYInRight(chart, shape.divIndex, shape.datas2[j])
						end
						if y1 >= y2
							paint.fillRect(shape.color, x - cWidth, y2, x + cWidth, y1)
						else
							paint.fillRect(shape.color, x - cWidth, y1, x + cWidth, y2)
						end
					else
						if shape.leftOrRight
							y2 = 0
							y2 = getChartY(chart, shape.divIndex, 0)
						else
							y2 = getChartYInRight(chart, shape.divIndex, 0)
						end
						if y1 >= y2
							paint.drawLine(shape.color2, 1, 0, x, y1, x, y2)
						else
							paint.drawLine(shape.color, 1, 0, x, y1, x, y2)
						end
						if j == lastValidIndex
							paint.drawLine(shape.color2, 1, 0, chart.leftVScaleWidth, y2, chart.size.cx - chart.rightVScaleWidth, y2)
						end
					end
				end
			elsif shape.shapeType == "text"
				for j in chart.firstVisibleIndex..lastValidIndex
					x = getChartX(chart, j)
					if shape.datas[j] != 0
						y1 = 0
						if shape.leftOrRight
							y1 = getChartY(chart, shape.divIndex, shape.value)
						else
							y1 = getChartYInRight(chart, shape.divIndex, shape.value)
						end
						drawText = shape.text
						tSize = paint.textSize(drawText, "Default,14")
						paint.drawText(drawText, shape.color, "Default,14", x - tSize.cx / 2, y1 - tSize.cy / 2)
					end
				end
			else
				if shape.leftOrRight
					if chart.selectShape == shape.shapeName
						drawChartLines(chart, paint, clipRect, shape.divIndex, shape.datas, shape.color, true)
					else
						drawChartLines(chart, paint, clipRect, shape.divIndex, shape.datas, shape.color, false)
					end
				else
					if chart.selectShape == shape.shapeName
						drawChartLinesInRight(chart, paint, clipRect, shape.divIndex, shape.datas, shape.color, true)
					else
						drawChartLinesInRight(chart, paint, clipRect, shape.divIndex, shape.datas, shape.color, false)
					end
				end
			end
		end
	end
end

#清除图形
#chart:图表
#paint:绘图对象
#clipRect:裁剪区域
def drawChart(chart, paint, clipRect)
	if chart.backColor != "none"
		paint.fillRect(chart.backColor, 0, 0, chart.size.cx, chart.size.cy)
	end
	if paint.onPaintChartScale != nil
		paint.onPaintChartScale.call(chart, paint, clipRect)
	else
		drawChartScale(chart, paint, clipRect)
	end
	if paint.onPaintChartStock != nil
		paint.onPaintChartStock.call(chart, paint, clipRect)
	else
		drawChartStock(chart, paint, clipRect)
	end
	if paint.onPaintChartPlot != nil
		paint.onPaintChartPlot.call(chart, paint, clipRect)
	else
		drawChartPlot(chart, paint, clipRect)
	end
	if paint.onPaintChartCrossLine != nil
		paint.onPaintChartCrossLine.call(chart, paint, clipRect)
	else
		drawChartCrossLine(chart, paint, clipRect)
	end
	if chart.borderColor != "none"
		paint.drawRect(chart.borderColor, chart.lineWidthChart, 0, 0, 0, chart.size.cx, chart.size.cy)
	end
end

#重绘视图 
#views:视图集合 
#paint:绘图对象 
#rect:区域
def renderViews(views, paint, rect)
	size = views.length
	for i in 0..size - 1
		view = views[i]
		if rect == nil
			subViews = view.views
			subViewsSize = subViews.length
			if subViewsSize > 0
				renderViews(subViews, paint, nil)
			end
			view.clipRect = nil
			next
		end
		if view.topMost == false && isPaintVisible(view) && view.allowDraw
			clx = clientX(view)
			cly = clientY(view)
			drawRect = FCRect.new(0, 0, view.size.cx, view.size.cy)
			clipRect = FCRect.new(clx, cly, clx + view.size.cx, cly + view.size.cy)
			destRect = FCRect.new(0, 0, 0, 0)
			if getIntersectRect(destRect, rect, clipRect) > 0
				view.clipRect = destRect
				paint.setOffset(clx, cly)
				paint.setClip(destRect.left - clx, destRect.top - cly, destRect.right - clx, destRect.bottom - cly)
				if paint.onPaint != nil
					paint.onPaint.call(view, paint, rect)
				else
					onPaintDefault(view, paint, rect)
				end
				subViews = view.views
				subViewsSize = subViews.length
				if(subViewsSize > 0)
					renderViews(subViews, paint, destRect)
				end
				paint.setOffset(clx, cly)
				paint.setClip(destRect.left - clx, destRect.top - cly, destRect.right - clx, destRect.bottom - cly)
				if paint.onPaintBorder != nil
					paint.onPaintBorder.call(view, paint, rect)
				else
					onPaintBorderDefault(view, paint, rect)
				end
			else
				subViews = view.views
				subViewsSize = subViews.length
				if subViewsSize > 0
					renderViews(subViews, paint, nil)
				end
				view.clipRect = nil
			end
		end
	end
	size = views.length
	for i in 0..size - 1
		view = views[i]
		if rect == nil
			subViews = view.views
			subViewsSize = subViews.length
			if subViewsSize > 0
				renderViews(subViews, paint, nil)
			end
			view.clipRect = nil
			next
		end
		if view.topMost == true && isPaintVisible(view) && view.allowDraw
			clx = clientX(view)
			cly = clientY(view)
			drawRect = FCRect.new(0, 0, view.size.cx, view.size.cy)
			clipRect = FCRect.new(clx, cly, clx + view.size.cx, cly + view.size.cy)
			destRect = FCRect.new(0, 0, 0, 0)
			if getIntersectRect(destRect, rect, clipRect) > 0
				view.clipRect = destRect
				paint.setOffset(clx, cly)
				paint.setClip(destRect.left - clx, destRect.top - cly, destRect.right - clx, destRect.bottom - cly)
				if paint.onPaint != nil
					paint.onPaint.call(view, paint, rect)
				else
					onPaintDefault(view, paint, rect)
				end
				subViews = view.views
				subViewsSize = subViews.leength
				if(subViewsSize > 0)
					renderViews(subViews, paint, destRect)
				end
				paint.setOffset(clx, cly)
				paint.setClip(destRect.left - clx, destRect.top - cly, destRect.right - clx, destRect.bottom - cly)
				if paint.onPaintBorder != nil
					paint.onPaintBorder.call(view, paint, rect)
				else
					onPaintBorderDefault(view, paint, rect)
				end
			else
				subViews = view.views
				subViewsSize = subViews.length
				if subViewsSize > 0
					renderViews(subViews, paint, nil)
				end
				view.clipRect = nil
			end
		end
	end
end	

#全局刷新方法
#views:视图集合
#paint:绘图对象
def invalidate(paint)
	if paint.onInvalidate != nil
		paint.onInvalidate.call(paint)
	else
		if paint.hWnd != 0
			$beginWmPaint.call(paint.hWnd)
			paint.clipRect = nil
			allRect = FCRect.new(0, 0, paint.size.cx / paint.scaleFactorX, paint.size.cy / paint.scaleFactorY)
			drawRect = allRect
			paint.beginPaint(allRect, drawRect)
			if paint.onRenderViews != nil
				paint.onRenderViews.call(paint.views, paint, drawRect)
			else
				renderViews(paint.views, paint, drawRect)
			end
			paint.endPaint()
			$endWmPaint.call(paint.hWnd)
		end
	end
end

#刷新视图方法
#view:视图
def invalidateView(view)
	if view.paint.onInvalidateView != nil
		view.paint.onInvalidateView.call(view)
	else
		if isPaintVisible(view)
			paint = view.paint
			if paint.hWnd != 0
				$beginWmPaint.call(paint.hWnd)
				paint.clipRect = nil
				clX = clientX(view)
				clY = clientY(view)
				drawRect = FCRect.new(clX, clY, clX + view.size.cx, clY + view.size.cy)
				allRect = FCRect.new(0, 0, paint.size.cx / paint.scaleFactorX, paint.size.cy / paint.scaleFactorY)
				paint.beginPaint(allRect, drawRect)
				if paint.onRenderViews != nil
					paint.onRenderViews.call(paint.views, paint, drawRect)
				else
					renderViews(paint.views, paint, drawRect)
				end
				paint.endPaint()
				$endWmPaint.call(paint.hWnd)
			end
		end
	end
end

#更新悬浮状态
#views:视图集合
def updateViewDefault(views)
	for i in 0..views.length - 1
		view = views[i]
		if view.exAttributes.has_key?("leftstr")
			pWidth = view.paint.size.cx / view.paint.scaleFactorX
			if view.parent != nil
				pWidth = view.parent.size.cx
			end
			newStr = view.exAttributes["leftstr"].gsub("%", "")
			view.location.x = (newStr.to_f * pWidth / 100).to_i
		end
		if view.exAttributes.has_key?("topstr")
			pHeight = view.paint.size.cy / view.paint.scaleFactorY
			if view.parent != nil
				pHeight = view.parent.size.cy
			end
			newStr = view.exAttributes["topstr"].gsub("%", "")
			view.location.y = (newStr.to_f * pHeight / 100).to_i
		end
		if view.exAttributes.has_key?("widthstr")
			pWidth = view.paint.size.cx / view.paint.scaleFactorX
			if view.parent != nil
				pWidth = view.parent.size.cx
			end
			newStr = view.exAttributes["widthstr"].gsub("%", "")
			view.size.cx = (newStr.to_f * pWidth / 100).to_i
		end
		if view.exAttributes.has_key?("heightstr")
			pHeight = view.paint.size.cy / view.paint.scaleFactorY
			if view.parent != nil
				pHeight = view.parent.size.cy
			end
			newStr = view.exAttributes["heightstr"].gsub("%", "")
			view.size.cy = (newStr.to_f * pHeight / 100).to_i
		end
		if(view.parent != nil && view.parent.viewType != "split")
			margin = view.margin
			padding = view.parent.padding
			if view.dock == "fill"
				view.location = FCPoint.new(margin.left + padding.left, margin.top + padding.top)
				vcx = view.parent.size.cx - margin.left - padding.left - margin.right - padding.right
				if vcx < 0
					vcx = 0
				end
				vcy = view.parent.size.cy - margin.top - padding.top - margin.bottom - padding.bottom
				if vcy < 0
					vcy = 0
				end
				view.size = FCSize.new(vcx, vcy)
			elsif view.dock == "left"
				view.location = FCPoint.new(margin.left + padding.left, margin.top + padding.top)
				vcy = view.parent.size.cy - margin.top - padding.top - margin.bottom - padding.bottom
				if vcy < 0
					vcy = 0
				end
				view.size = FCSize.new(view.size.cx, vcy)
			elsif view.dock == "top"
				view.location = FCPoint.new(margin.left + padding.left, margin.top + padding.top)
				vcx = view.parent.size.cx - margin.left - padding.left - margin.right - padding.right
				if vcx < 0
					vcx = 0
				end
				view.size = FCSize.new(vcx, view.size.cy)
			elsif view.dock == "right"
				view.location = FCPoint.new(view.parent.size.cx - view.size.cx - padding.right - margin.right, margin.top + padding.top)
				vcy = view.parent.size.cy - margin.top - padding.top - margin.bottom - padding.bottom
				if vcy < 0
					vcy = 0
				end
				view.size = FCSize.new(view.size.cx, vcy)
			elsif view.dock == "bottom"
				view.location = FCPoint.new(margin.left + padding.left, view.parent.size.cy - view.size.cy - margin.bottom - padding.bottom)
				vcx = view.parent.size.cx - margin.left - padding.left - margin.right - padding.right
				if vcx < 0
					vcx = 0
				end
				view.size = FCSize.new(vcx, view.size.cy)
			end
			if view.align == "center"
				view.location = FCPoint.new((view.parent.size.cx - view.size.cx) / 2, view.location.y)
			elsif view.align == "right"
				view.location = FCPoint.new(view.parent.size.cx - view.size.cx - padding.right - margin.right, view.location.y)
			end
			if view.verticalAlign == "middle"
				view.location = FCPoint.new(view.location.x, (view.parent.size.cy - view.size.cy) / 2)
			elsif view.verticalAlign == "bottom"
				view.location = FCPoint.new(view.location.x, view.parent.size.cy - view.size.cy - padding.bottom - margin.bottom)
			end
		elsif view.parent == nil
			if view.dock == "fill"
				view.size = FCSize.new(view.paint.size.cx / view.paint.scaleFactorX, view.paint.size.cy / view.paint.scaleFactorY)
			end
		end
		if view.viewType == "split"
			resetSplitLayoutDiv(view)
		elsif view.viewType == "tabview"
			updateTabLayout(view)
		elsif view.viewType == "layout"
			resetLayoutDiv(view)
		elsif view.viewType == "chart"
			chart = view
			resetChartVisibleRecord(chart)
			checkChartLastVisibleIndex(chart)
			if chart.paint.onCalculateChartMaxMin != nil
				chart.paint.onCalculateChartMaxMin.call(chart)
			else
				calculateChartMaxMin(chart)
			end
		elsif view.viewType == "calendar"
			updateCalendar(view)
		end
		subViews = view.views
		if subViews.length > 0
			updateViewDefault(subViews)
		end
	end
end

#视图尺寸改变
def windowResize(rect, resizePoint, nowPoint, startTouchPoint)
	if resizePoint == 0
		rect.left = rect.left + nowPoint.x - startTouchPoint.x
		rect.top = rect.top + nowPoint.y - startTouchPoint.y
	elsif resizePoint == 1
		rect.left = rect.left + nowPoint.x - startTouchPoint.x
		rect.bottom = rect.bottom + nowPoint.y - startTouchPoint.y
	elsif resizePoint == 2
		rect.right = rect.right + nowPoint.x - startTouchPoint.x
		rect.top = rect.top + nowPoint.y - startTouchPoint.y
	elsif resizePoint == 3
		rect.right = rect.right + nowPoint.x - startTouchPoint.x
		rect.bottom = rect.bottom + nowPoint.y - startTouchPoint.y
	elsif resizePoint == 4
		rect.left = rect.left + nowPoint.x - startTouchPoint.x
	elsif resizePoint == 5
		rect.top = rect.top + nowPoint.y - startTouchPoint.y
	elsif resizePoint == 6
		rect.right = rect.right + nowPoint.x - startTouchPoint.x
	elsif resizePoint == 7
		rect.bottom = rect.bottom + nowPoint.y - startTouchPoint.y
	end
end

#获取调整尺寸的点
def getResizeState(view, mp)
	bWidth = 5
	width = view.size.cx
	height = view.size.cy
	if mp.x >= 0 && mp.x <= bWidth * 2 && mp.y >= 0 && mp.y <= bWidth * 2
		return 0;
	elsif mp.x >= 0 && mp.x <= bWidth * 2 && mp.y >= height - bWidth * 2 && mp.y <= height
		return 1;
	elsif mp.x >= width - bWidth * 2 && mp.x <= width && mp.y >= 0 && mp.y <= bWidth * 2
		return 2;
	elsif mp.x >= width - bWidth * 2 && mp.x <= width && mp.y >= height - bWidth * 2 && mp.y <= height
		return 3;
	elsif mp.x >= 0 && mp.x <= bWidth && mp.y >= 0 && mp.y <= height
		return 4;
	elsif mp.x >= 0 && mp.x <= width && mp.y >= 0 && mp.y <= bWidth
		return 5;
	elsif mp.x >= width - bWidth && mp.x <= width && mp.y >= 0 && mp.y <= height
		return 6;
	elsif mp.x >= 0 && mp.x <= width && mp.y >= height - bWidth && mp.y <= height
		return 7;
	else
		return -1
	end
end

#鼠标移动方法
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
#paint 绘图对象
def handleMouseMove(mp, buttons, clicks, delta, paint)
	if paint.touchDownView != nil
		paint.touchMoveView = paint.touchDownView
		cmpPoint = FCPoint.new(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView))
		if paint.onMouseMove != nil
			paint.onMouseMove.call(paint.touchDownView, cmpPoint, buttons, clicks, 0)
		else
			onMouseMoveDefault(paint.touchDownView, cmpPoint, buttons, clicks, 0)
		end
		if paint.isDoubleClick == false
			if paint.focusedView != nil && paint.focusedView.exView
				pName = Fiddle::Pointer[paint.focusedView.viewName]
				$mouseMoveView.call(paint.gID.to_i, pName, cmpPoint.x.to_i, cmpPoint.y.to_i, 1, 1)
				invalidateView(paint.focusedView)
			end
		end
		if paint.touchDownView.resizePoint != -1
			newBounds = FCRect.new(paint.touchDownView.startRect.left, paint.touchDownView.startRect.top, paint.touchDownView.startRect.right, paint.touchDownView.startRect.bottom)
			windowResize(newBounds, paint.touchDownView.resizePoint, mp, paint.touchDownPoint)
			paint.touchDownView.location = FCPoint.new(newBounds.left, newBounds.top)
			paint.touchDownView.size = FCSize.new(newBounds.right - newBounds.left, newBounds.bottom - newBounds.top)
			if paint.touchDownView.parent != nil
				invalidateView(paint.touchDownView.parent)
			else
				invalidate(paint)
			end
		elsif paint.touchDownView.allowDrag
			if (mp.x - paint.touchDownPoint.x).abs > 5 || (mp.y - paint.touchDownPoint.y).abs > 5
				paint.dragBeginRect = FCRect.new(paint.touchDownView.location.x, paint.touchDownView.location.y, paint.touchDownView.location.x + paint.touchDownView.size.cx, paint.touchDownView.location.y + paint.touchDownView.size.cy)
				paint.dragBeginPoint = FCPoint.new(paint.touchDownPoint.x, paint.touchDownPoint.y)
				paint.draggingView = paint.touchDownView
				paint.touchDownView = nil
			end
		end
	elsif paint.draggingView != nil && buttons == 1
		offsetX = mp.x - paint.dragBeginPoint.x
		offsetY = mp.y - paint.dragBeginPoint.y
		newBounds = FCRect.new(paint.dragBeginRect.left + offsetX, paint.dragBeginRect.top + offsetY, paint.dragBeginRect.right + offsetX, paint.dragBeginRect.bottom + offsetY)
		paint.draggingView.location = FCPoint.new(newBounds.left, newBounds.top)
		if paint.draggingView.parent != nil && paint.draggingView.parent.viewType == "split"
			resetSplitLayoutDiv(paint.draggingView.parent)
			if paint.onUpdateView != nil
				paint.onUpdateView.call(paint.draggingView.parent.views)
			else
				updateViewDefault(paint.draggingView.parent.views)
			end
		end
		if paint.draggingView.parent != nil
			invalidateView(paint.draggingView.parent)
		else
			invalidate(paint)
		end
	else
		topViews = paint.views
		view = findView(mp, topViews)
		cmpPoint = FCPoint.new(mp.x - clientX(view), mp.y - clientY(view))
		if view != nil
			oldMouseMoveView = paint.touchMoveView
			paint.touchMoveView = view
			if oldMouseMoveView != nil && oldMouseMoveView != view
				if paint.onMouseLeave != nil
					paint.onMouseLeave.call(oldMouseMoveView, cmpPoint, buttons, clicks, 0)
				end
				invalidateView(oldMouseMoveView)
			end
			if oldMouseMoveView == nil || oldMouseMoveView != view
				if paint.onMouseEnter != nil
					paint.onMouseEnter.call(view, cmpPoint, buttons, clicks, 0)			
				end
				pCursor = Fiddle::Pointer[view.cursor]
				$setCursor.call(paint.gID.to_i, pCursor)
			end
			if paint.onMouseMove != nil
				paint.onMouseMove.call(view, cmpPoint, buttons, clicks, 0)
			else
				onMouseMoveDefault(view, cmpPoint, buttons, clicks, 0)
			end
		end
	end
end

#鼠标按下方法
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
#paint 绘图对象
def handleMouseDown(mp, buttons, clicks, delta, paint)
	if clicks == 2
		paint.isDoubleClick = true
	else
		paint.isDoubleClick = false
	end
	paint.cancelClick = false
	paint.touchDownPoint = mp
	autoHideView(paint.touchDownPoint, paint)
	topViews = paint.views
	lastFocusedView = paint.focusedView
	paint.touchDownView = findView(mp, topViews)
	checkShowMenu(paint)
	if paint.touchDownView != nil
		if paint.focusedView != nil && paint.focusedView != paint.touchDownView && paint.focusedView.exView
			pName = Fiddle::Pointer[paint.focusedView.viewName]
			$unFocusView.call(paint.gID.to_i, pName)
			invalidateView(paint.focusedView)	
		end
		paint.focusedView = paint.touchDownView
		cmpPoint = FCPoint.new(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView))
		if paint.onMouseDown != nil
			paint.onMouseDown.call(paint.touchDownView, cmpPoint, buttons, clicks, 0)
		else
			onMouseDownDefault(paint.touchDownView, cmpPoint, buttons, clicks, 0)
		end
		if paint.focusedView != nil && paint.focusedView.exView
			pName = Fiddle::Pointer[paint.focusedView.viewName]
			$focusView.call(paint.gID.to_i, pName)
			$mouseDownView.call(paint.gID.to_i, pName, cmpPoint.x.to_i, cmpPoint.y.to_i, buttons.to_i, clicks.to_i)
			invalidateView(paint.focusedView)
		end
		if paint.touchDownView.allowResize
			paint.touchDownView.resizePoint = getResizeState(paint.touchDownView, cmpPoint)
			if paint.touchDownView.resizePoint != -1
				paint.touchDownView.startRect = FCRect.new(paint.touchDownView.location.x, paint.touchDownView.location.y, paint.touchDownView.location.x + paint.touchDownView.size.cx, paint.touchDownView.location.y + paint.touchDownView.size.cy)
			end
		end
	end
end

#鼠标抬起方法
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
#paint 绘图对象
def handleMouseUp(mp, buttons, clicks, delta, paint)
	paint.isDoubleClick = false
	if paint.touchDownView != nil
		cmpPoint = FCPoint.new(mp.x - clientX(paint.touchDownView), mp.y - clientY(paint.touchDownView))
		topViews = paint.views
		view = findView(mp, topViews)
		if view != nil && view == paint.touchDownView
			if paint.cancelClick == false
				if paint.onClick != nil
					paint.onClick.call(paint.touchDownView, true, cmpPoint, false, cmpPoint, clicks)
				else
					onClickDefault(paint.touchDownView, true, cmpPoint, false, cmpPoint, clicks)
				end
			end
		end
		if paint.touchDownView != nil
			mouseDownView = paint.touchDownView
			paint.touchDownView.resizePoint = -1
			paint.touchDownView = nil
			paint.touchMoveView = nil
			if paint.onMouseUp != nil
				paint.onMouseUp.call(mouseDownView, cmpPoint, buttons, clicks, 0)
			else
				onMouseUpDefault(mouseDownView, cmpPoint, buttons, clicks, 0)
			end
			if paint.focusedView != nil && paint.focusedView.exView
				pName = Fiddle::Pointer[paint.focusedView.viewName]
				$focusView.call(paint.gID.to_i, pName)
				$mouseUpView.call(paint.gID.to_i, pName, cmpPoint.x.to_i, cmpPoint.y.to_i, buttons.to_i, clicks.to_i)
				invalidateView(paint.focusedView)
			end
		end
	end
	paint.draggingView = nil
end

#鼠标滚动方法
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
#paint 绘图对象
def handleMouseWheel(mp, buttons, clicks, delta, paint)
	topViews = paint.views
	view = findView(mp, topViews)
	if view != nil
		cmpPoint = FCPoint.new(mp.x - clientX(view), mp.y - clientY(view))
		if paint.onMouseWheel != nil
			paint.onMouseWheel.call(view, cmpPoint, buttons, clicks, delta)
		else
			onMouseWheelDefault(view, cmpPoint, buttons, clicks, delta)
		end
		if view.exView
			pName = Fiddle::Pointer[view.viewName]
			$mouseWheelView.call(paint.gID.to_i, pName, cmpPoint.x.to_i, cmpPoint.y.to_i, buttons.to_i, clicks.to_i, delta.to_i)
			invalidateView(view)	
		end
	end
end

#获取月的日数
#year:年
#month:月
def getDaysInMonth(year, month)
	if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12
		return 31
	elsif month == 4 || month == 6 || month == 9 || month == 11
		return 30
	else
		if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0
				return 29
		else
			return 28
		end
	end
end

#根据字符获取月份
#month:月
def getMonthStr(month)
	if month == 1
		return "一月"
	elsif month == 2
		return "二月"
	elsif month == 3
		return "三月"
	elsif month == 4
		return "四月"
	elsif month == 5
		return "五月"
	elsif month == 6
		return "六月"
	elsif month == 7
		return "七月"
	elsif month == 8
		return "八月"
	elsif month == 9
		return "九月"
	elsif month == 10
		return "十月"
	elsif month == 11
		return "十一月"
	elsif month == 12
		return "十二月"
	else
		return ""
	end
end

#获取年
#years:年的集合
#year:年
def getYear(years, year)
	cy = nil
	if !years.has_key?(year)
		cy = CYear.new()
		cy.year = year
		years[year] = cy
		for i in 1..12
			cMonth = CMonth.new()
			cMonth.year = year
			cMonth.month = i
			cy.months[i] = cMonth
			daysInMonth = getDaysInMonth(year, i)
			for j in 1..daysInMonth
				cDay = CDay.new()
				cDay.year = year
				cDay.month = i
				cDay.day = j
				cMonth.days[j] = cDay
			end
		end
	else
		cy = years[year]
	end
	return cy
end

#显示隐藏日期层
#dayDiv:日期层
#visible:是否可见
def showOrHideDayDiv(dayDiv, visible)
	dayButtonSize = dayDiv.dayButtons.length
	for i in 0..dayButtonSize - 1
		dayButton = dayDiv.dayButtons[i]
		dayButton.visible = visible
	end
end

#显示隐藏月层
#monthDiv:月层
#visible:是否可见
def showOrHideMonthDiv(monthDiv, visible)
	monthButtonSize = monthDiv.monthButtons.length
	for i in 0..monthButtonSize - 1
		monthButton = monthDiv.monthButtons[i]
		monthButton.visible = visible
	end
end

#显示隐藏年层
#yearButtons:年层
#visible:是否可见
def showOrHideYearDiv(yearDiv, visible)
	yearButtonSize = yearDiv.yearButtons.length
	for i in 0..yearButtonSize - 1
		yearButton = yearDiv.yearButtons[i]
		yearButton.visible = visible
	end
end

#初始化日历
#calendar:日历
def initCalendar(calendar)
	calendar.dayDiv.calendar = calendar
	calendar.monthDiv.calendar = calendar
	calendar.yearDiv.calendar = calendar
	for i in 0..41
		dayButton = DayButton.new()
		dayButton.calendar = calendar
		calendar.dayDiv.dayButtons.push(dayButton)
		dayFCButtonm = DayButton.new()
		dayFCButtonm.calendar = calendar
		dayFCButtonm.visible = false
		calendar.dayDiv.dayButtons_am.push(dayFCButtonm)
	end
	for i in 0..11
		monthButton = MonthButton.new()
		monthButton.calendar = calendar
		monthButton.month = (i + 1)
		calendar.monthDiv.monthButtons.push(monthButton)
		monthButtonAm = MonthButton.new()
		monthButtonAm.calendar = calendar
		monthButtonAm.visible = false
		monthButtonAm.month = (i + 1)
		calendar.monthDiv.monthButtons_am.push(monthButtonAm)
	end
	for i in 0..11
		yearButton = YearButton.new()
		yearButton.calendar = calendar
		calendar.yearDiv.yearButtons.push(yearButton)
		yearButtonAm = YearButton.new()
		yearButtonAm.calendar = calendar
		yearButtonAm.visible = false
		calendar.yearDiv.yearButtons_am.push(yearButtonAm)
	end
	calendar.headDiv.calendar = calendar
	calendar.timeDiv.calendar = calendar
end

#获取星期
#y:年
#m:月
#d:日
def dayOfWeek(y, m, d)
	if m == 1 || m == 2
		m += 12
		y = y - 1
	end
	return (((d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) + 1) % 7).to_i
end

#获取当月
#calendar:日历
def getMonth(calendar)
	return getYear(calendar.years, calendar.selectedDay.year).months[calendar.selectedDay.month]
end

#获取下个月
#calendar:日历
#year:年
#month:月
def getNextMonth(calendar, year, month)
	nextMonth = month + 1
	nextYear = year
	if nextMonth == 13
		nextMonth = 1
		nextYear += 1
	end
	return getYear(calendar.years, nextYear).months[nextMonth]
end

#获取上个月
#calendar:日历
#year:年
#month:月
def getLastMonth(calendar, year, month)
	lastMonth = month - 1
	lastYear = year
	if lastMonth == 0
		lastMonth = 12
		lastYear -= 1
	end
	return getYear(calendar.years, lastYear).months[lastMonth]
end

#重置日期层布局
#dayDiv:日期层
#state:状态
def resetDayDiv(dayDiv, state)
	calendar = dayDiv.calendar
	thisMonth = getMonth(calendar)
	lastMonth = getLastMonth(calendar, thisMonth.year, thisMonth.month)
	nextMonth = getNextMonth(calendar, thisMonth.year, thisMonth.month)
	left = 0
	headHeight = calendar.headDiv.bounds.bottom
	top = headHeight
	width = calendar.size.cx
	height = calendar.size.cy
	height -= calendar.timeDiv.bounds.bottom - calendar.timeDiv.bounds.top
	dayButtonHeight = height - headHeight
	if dayButtonHeight < 1
		dayButtonHeight = 1
	end
	toY = 0
	if dayDiv.aDirection == 1
		toY = dayButtonHeight * dayDiv.aTick / dayDiv.aTotalTick
		if state == 1
			thisMonth = nextMonth
			month = thisMonth.month
			lastMonth = getLastMonth(calendar, thisMonth.year, month)
			nextMonth = getNextMonth(calendar, thisMonth.year, month)
		end
	elsif dayDiv.aDirection == 2
		toY = -dayButtonHeight * dayDiv.aTick / dayDiv.aTotalTick
		if state == 1
			thisMonth = lastMonth
			month = thisMonth.month
			lastMonth = getLastMonth(calendar, thisMonth.year, month)
			nextMonth = getNextMonth(calendar, thisMonth.year, month)
		end
	end
	buttonSize = 0
	if state == 0
		buttonSize = dayDiv.dayButtons.length
	elsif state == 1
		buttonSize = dayDiv.dayButtons_am.length
	end
	dheight = dayButtonHeight / 6
	days = thisMonth.days
	firstDay = days[1]
	startDayOfWeek = dayOfWeek(firstDay.year, firstDay.month, firstDay.day)
	for i in 0..buttonSize - 1
		dayButton = nil
		if state == 0
			dayButton = dayDiv.dayButtons[i]
			buttonSize = dayDiv.dayButtons.length
		elsif state == 1
			dayButton = dayDiv.dayButtons_am[i]
			buttonSize = dayDiv.dayButtons_am.length
		end
		if i == 35
			dheight = height - top
		end
		vOffset = 0
		if state == 1
			if dayDiv.aTick > 0
				dayButton.visible = true
				if dayDiv.aDirection == 1
					vOffset = toY - dayButtonHeight
				elsif dayDiv.aDirection == 2
					vOffset = toY + dayButtonHeight
				end
			else
				dayButton.visible = false
				next
			end
		else
			vOffset = toY
		end
		if (i + 1) % 7 == 0
			dp = FCPoint.new(left, top + vOffset)
			ds = FCSize.new(width - left, dheight)
			bounds = FCRect.new(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy)
			dayButton.bounds = bounds
			left = 0
			if i != 0 && i != buttonSize - 1
				top += dheight
			end
		else
			dp = FCPoint.new(left, top + vOffset)
			ds = FCSize.new(width / 7 + ((i + 1) % 7) % 2, dheight)
			bounds = FCRect.new(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy)
			dayButton.bounds = bounds
			left += ds.cx
		end
		cDay = nil
		dayButton.inThisMonth = false
		if i >= startDayOfWeek && i <= startDayOfWeek + days.length - 1
			cDay = days[i - startDayOfWeek + 1]
			dayButton.inThisMonth = true
		elsif i < startDayOfWeek
			cDay = lastMonth.days[lastMonth.days.length - startDayOfWeek + i + 1]
		elsif i > startDayOfWeek + days.length - 1
			cDay = nextMonth.days[i - startDayOfWeek - days.length + 1]
		end
		dayButton.day = cDay
		if state == 0 && dayButton.day && dayButton.day == calendar.selectedDay
			dayButton.selected = true
		else
			dayButton.selected = false
		end
	end
end

#重置月层布局
#monthDiv:月层
#state:状态
def resetMonthDiv(monthDiv, state)
	calendar = monthDiv.calendar
	thisYear = monthDiv.year
	lastYear = monthDiv.year - 1
	nextYear = monthDiv.year + 1
	left = 0
	headHeight = calendar.headDiv.bounds.bottom
	top = headHeight
	width = calendar.size.cx
	height = calendar.size.cy
	height -= calendar.timeDiv.bounds.bottom - calendar.timeDiv.bounds.top
	monthButtonHeight = height - top
	if monthButtonHeight < 1
		monthButtonHeight = 1
	end
	toY = 0
	monthButtons = nil
	if monthDiv.aDirection == 1
		toY = monthButtonHeight * monthDiv.aTick / monthDiv.aTotalTick
		if state == 1
			thisYear = nextYear
			lastYear = thisYear - 1
			nextYear = thisYear + 1
		end
	elsif monthDiv.aDirection == 2
		toY = -monthButtonHeight * monthDiv.aTick / monthDiv.aTotalTick
		if state == 1
			thisYear = lastYear
			lastYear = thisYear - 1
			nextYear = thisYear + 1
		end
	end
	if state == 0
		monthButtons = monthDiv.monthButtons
	elsif state == 1
		monthButtons = monthDiv.monthButtons_am
	end
	dheight = monthButtonHeight / 3
	buttonSize = monthButtons.length
	for i in 0..buttonSize - 1
		if i == 8
			dheight = height - top
		end
		monthButton = monthButtons[i]
		monthButton.year = thisYear
		vOffSet = 0
		if state == 1
			if monthDiv.aTick > 0
				monthButton.visible = true
				if monthDiv.aDirection == 1
					vOffSet = toY - monthButtonHeight
				elsif monthDiv.aDirection == 2
					vOffSet = toY + monthButtonHeight
				end
			else
				monthButton.visible = false
				next
			end
		else
			vOffSet = toY
		end
		if (i + 1) % 4 == 0
			dp = FCPoint.new(left, top + vOffSet)
			ds = FCSize.new(width - left, dheight)
			bounds = FCRect.new(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy)
			monthButton.bounds = bounds
			left = 0
			if i != 0 && i != buttonSize - 1
				top += dheight
			end
		else
			dp = FCPoint.new(left, top + vOffSet)
			ds = FCSize.new( width / 4 + ((i + 1) % 4) % 2, dheight)
			bounds = FCRect.new(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy)
			monthButton.bounds = bounds
			left += ds.cx
		end
	end
end

#重置年层布局
#yearDiv:年层
#state:状态
def resetYearDiv(yearDiv, state)
	calendar = yearDiv.calendar
	thisStartYear = yearDiv.startYear
	lastStartYear = yearDiv.startYear - 12
	nextStartYear = yearDiv.startYear + 12
	left = 0
	headHeight = calendar.headDiv.bounds.bottom
	top = headHeight
	width = calendar.size.cx
	height = calendar.size.cy
	height -= calendar.timeDiv.bounds.bottom - calendar.timeDiv.bounds.top
	yearButtonHeight = height - top
	if yearButtonHeight < 1
		yearButtonHeight = 1
	end
	toY = 0
	yearButtons = nil
	if yearDiv.aDirection == 1
		toY = yearButtonHeight * yearDiv.aTick / yearDiv.aTotalTick
		if state == 1
			thisStartYear = nextStartYear
			lastStartYear = thisStartYear - 12
			nextStartYear = thisStartYear + 12
		end
	elsif yearDiv.aDirection == 2
		toY = -yearButtonHeight * yearDiv.aTick / yearDiv.aTotalTick
		if state == 1
			thisStartYear = lastStartYear
			lastStartYear = thisStartYear - 12
			nextStartYear = thisStartYear + 12
		end
	end
	if state == 0
		yearButtons = yearDiv.yearButtons
	elsif state == 1
		yearButtons = yearDiv.yearButtons_am
	end
	dheight = yearButtonHeight / 3
	buttonSize = yearDiv.yearButtons.length
	for i in 0..buttonSize - 1
		if i == 8
			dheight = height - top
		end
		yearButton = yearButtons[i]
		yearButton.year = thisStartYear + i
		vOffSet = 0
		if state == 1
			if yearDiv.aTick > 0
				yearButton.visible = true
				if yearDiv.aDirection == 1
					vOffSet = toY - yearButtonHeight
				elsif yearDiv.aDirection == 2
					vOffSet = toY + yearButtonHeight
				end
			else
				yearButton.visible = false
				next
			end
		else
			vOffSet = toY
		end
		if (i + 1) % 4 == 0
			dp = FCPoint.new(left, top + vOffSet)
			ds = FCSize.new(width - left, dheight)
			bounds = FCRect.new(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy)
			yearButton.bounds = bounds
			left = 0
			if i != 0 && i != buttonSize - 1
				top += dheight
			end
		else
			dp = FCPoint.new(left, top + vOffSet)
			ds = FCSize.new(width / 4 + ((i + 1) % 4) % 2, dheight)
			bounds = FCRect.new(dp.x, dp.y, dp.x + ds.cx, dp.y + ds.cy)
			yearButton.bounds = bounds
			left += ds.cx
		end
	end
end

#选择开始年份
#yearDiv:年层
#startYear:开始年
def selectStartYear(yearDiv, startYear)
	if yearDiv.startYear != startYear
		if startYear > yearDiv.startYear
			yearDiv.aDirection = 1
		else
			yearDiv.aDirection = 2
		end
		if yearDiv.calendar.useAnimation
			yearDiv.aTick = yearDiv.aTotalTick
		end
		yearDiv.startYear = startYear
	end
end

#选择年份
#monthDiv:月层
#year:年
def selectYear(monthDiv, year)
	if monthDiv.year != year
		if year > monthDiv.year
			monthDiv.aDirection = 1
		else
			monthDiv.aDirection = 2
		end
		if monthDiv.calendar.useAnimation
			monthDiv.aTick = monthDiv.aTotalTick
		end
		monthDiv.year = year
	end
end

#选中日期
#dayDiv:日期层
#selectedDay:选中日
#lastDay:上一日
def selectDay(dayDiv, selectedDay, lastDay)
	calendar = dayDiv.calendar
	m = getYear(calendar.years, selectedDay.year).months[selectedDay.month]
	thisMonth = getYear(calendar.years, lastDay.year).months[lastDay.month]
	if m != thisMonth
		if thisMonth.year * 12 + thisMonth.month > m.year * 12 + m.month
			dayDiv.aDirection = 2
		else
			dayDiv.aDirection = 1
		end
		i = 0
		buttonSize = dayDiv.dayButtons.length
		for i in 0..buttonSize - 1
			dayButton = dayDiv.dayButtons[i]
			if (dayDiv.aDirection == 1 && dayButton.day == thisMonth.days[0]) || (dayDiv.aDirection == 2 && dayButton.day == thisMonth.days[thisMonth.days.length - 1])
				dayDiv.aClickRowFrom = i / 7
				if i % 7 != 0
					dayDiv.aClickRowFrom += 1
				end
			end
		end
		resetDayDiv(dayDiv, 0)
		buttonSize = dayDiv.dayButtons_am.length
		for i in 0..buttonSize - 1
			dayFCButtonm = dayDiv.dayButtons_am[i]
			if (dayDiv.aDirection == 1 && dayFCButtonm.day == m.days[0]) || (dayDiv.aDirection == 2 && dayFCButtonm.day == m.days[m.days.length - 1])
				dayDiv.aClickRowTo = i / 7
				if i % 7 != 0
					dayDiv.aClickRowTo += 1
				end
			end
		end
		if calendar.useAnimation
			dayDiv.aTick = dayDiv.aTotalTick
		end
	else
		dayButtonsSize = dayDiv.dayButtons.length
		for i in 0..dayButtonsSize - 1
			dayButton = dayDiv.dayButtons[i]
			if dayButton.day != selectedDay
				dayButton.selected = false
			end
		end
	end
end

#日历的秒表
#calendar:日历
def calendarTimer(calendar)
	paint = false
	if calendar.dayDiv.aTick > 0
		calendar.dayDiv.aTick = (calendar.dayDiv.aTick * 2 / 3).to_i
		paint = true
	end
	if calendar.monthDiv.aTick > 0
		calendar.monthDiv.aTick = (calendar.monthDiv.aTick * 2 / 3).tp_i
		paint = true
	end
	if calendar.yearDiv.aTick > 0
		calendar.yearDiv.aTick = (calendar.yearDiv.aTick * 2 / 3).to_i
		paint = true
	end
	if paint 
		updateCalendar(calendar)
		if calendar.paint != nil
			invalidateView(calendar)
		end
	end
end

#更新日历的布局
#calendar:日历
def updateCalendar(calendar)
	calendar.headDiv.bounds = FCRect.new(0, 0, calendar.size.cx, 80)
	if calendar.mode == "day"
		resetDayDiv(calendar.dayDiv, 0)
		resetDayDiv(calendar.dayDiv, 1)
	elsif calendar.mode == "month"
		resetMonthDiv(calendar.monthDiv, 0)
		resetMonthDiv(calendar.monthDiv, 1)
	elsif calendar.mode == "year"
		resetYearDiv(calendar.yearDiv, 0)
		resetYearDiv(calendar.yearDiv, 1)
	end
end

#绘制头部层
#headDiv:头部层
#paint:绘图对象
def drawHeadDiv(headDiv, paint)
	calendar = headDiv.calendar
	bounds = headDiv.bounds
	if headDiv.backColor != "none"
		paint.fillRect(headDiv.backColor, bounds.left, bounds.top, bounds.right, bounds.bottom)
	end
	weekStrings = []
	weekStrings.push("周日")
	weekStrings.push("周一")
	weekStrings.push("周二")
	weekStrings.push("周三")
	weekStrings.push("周四")
	weekStrings.push("周五")
	weekStrings.push("周六")
	w = bounds.right - bounds.left
	left = bounds.left
	for i in 0..6
		weekDaySize = paint.textSize(weekStrings[i], headDiv.weekFont)
		textX = left + (w / 7) / 2 - weekDaySize.cx / 2
		textY = bounds.bottom - weekDaySize.cy - 2
		paint.drawText(weekStrings[i], headDiv.textColor, headDiv.weekFont, textX, textY)
		left += w / 7
	end
	drawTitle = ""
	if calendar.mode == "day"
		drawTitle = calendar.selectedDay.year.to_s + "年" + calendar.selectedDay.month.to_s + "月"
	elsif calendar.mode == "month"
		drawTitle = calendar.monthDiv.year.to_s + "年"
	else
		drawTitle = calendar.yearDiv.startYear.to_s + "年-" + (calendar.yearDiv.startYear + 11).to_s + "年"
	end
	tSize = paint.textSize(drawTitle, headDiv.titleFont)
	paint.drawText(drawTitle, headDiv.textColor, headDiv.titleFont, bounds.left + (w - tSize.cx) / 2, 30)
	tR = 10
	#画左右三角
	drawPoints = []
	drawPoints.push(FCPoint.new(5, bounds.top + (bounds.bottom - bounds.top) / 2))
	drawPoints.push(FCPoint.new(5 + tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 - tR))
	drawPoints.push(FCPoint.new(5 + tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 + tR))
	paint.fillPolygon(headDiv.arrowColor, drawPoints)
	drawPoints = []
	drawPoints.push(FCPoint.new(bounds.right - 5, bounds.top + (bounds.bottom - bounds.top) / 2))
	drawPoints.push(FCPoint.new(bounds.right - 5 - tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 - tR))
	drawPoints.push(FCPoint.new(bounds.right - 5 - tR * 2, bounds.top + (bounds.bottom - bounds.top) / 2 + tR))
	paint.fillPolygon(headDiv.arrowColor, drawPoints)
end

#绘制日的按钮
#dayButton:日期按钮
#paint:绘图对象
def drawDayButton(dayButton, paint)
	if dayButton.day != nil
		calendar = dayButton.calendar
		bounds = dayButton.bounds
		text = (dayButton.day.day).to_s
		tSize = paint.textSize(text, dayButton.font)
		if dayButton.backColor != "none"
			paint.fillRect(dayButton.backColor, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2)
		end
		if dayButton.inThisMonth
			paint.drawText(text, dayButton.textColor, dayButton.font, bounds.left + 5, bounds.top + 7)
		else
			paint.drawText(text, dayButton.textColor2, dayButton.font, bounds.left + 5, bounds.top + 7)
		end
		if dayButton.borderColor != "none"
			paint.drawRect(dayButton.borderColor, 1, 0, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2)
		end
	end
end

#绘制月的按钮
#monthButton:月按钮
#paint:绘图对象
def drawMonthButton(monthButton, paint)
	calendar = monthButton.calendar
    bounds = monthButton.bounds
    text = getMonthStr(monthButton.month)
    tSize = paint.textSize(text, monthButton.font)
    if monthButton.backColor != "none"
        paint.fillRect(monthButton.backColor, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2)
	end
    paint.drawText(text, monthButton.textColor, monthButton.font, bounds.left + 5, bounds.top + 7)
    if monthButton.borderColor != "none"
        paint.drawRect(monthButton.borderColor, 1, 0, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2)
	end
end

#绘制年的按钮
#yearButton:年按钮
#paint:绘图对象
def drawYearButton(yearButton, paint)
	calendar = yearButton.calendar
    bounds = yearButton.bounds
    text = (yearButton.year).to_s
    tSize = paint.textSize(text, yearButton.font)
    if yearButton.backColor != "none"
        paint.fillRect(yearButton.backColor, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2)
	end
    paint.drawText(text, yearButton.textColor, yearButton.font, bounds.left + 5, bounds.top + 7)
    if yearButton.borderColor != "none"
        paint.drawRect(yearButton.borderColor, 1, 0, bounds.left + 2, bounds.top + 2, bounds.right - 2, bounds.bottom - 2)
	end
end

#绘制日历
#calendar:日历
#paint:绘图对象
def drawCalendar(calendar, paint)
	if calendar.backColor != "none"
		paint.fillRect(calendar.backColor, 0, 0, calendar.size.cx, calendar.size.cy)
	end
	if calendar.mode == "day"
		dayButtonsSize = calendar.dayDiv.dayButtons.length
		for i in 0..dayButtonsSize - 1
			dayButton = calendar.dayDiv.dayButtons[i]
			if dayButton.visible
				if paint.onPaintCalendarDayButton != nil
					paint.onPaintCalendarDayButton.call(dayButton, paint)
				else
					drawDayButton(dayButton, paint)
				end
			end
		end
		dayFCButtonmSize = calendar.dayDiv.dayButtons_am.length
		for i in 0..dayFCButtonmSize - 1
			dayButton = calendar.dayDiv.dayButtons_am[i]
			if dayButton.visible
				if paint.onPaintCalendarDayButton != nil
					paint.onPaintCalendarDayButton.call(dayButton, paint)
				else
					drawDayButton(dayButton, paint)
				end
			end
		end
	elsif calendar.mode == "month"
		monthButtonsSize = calendar.monthDiv.monthButtons.length
		for i in 0..monthButtonsSize - 1
			monthButton = calendar.monthDiv.monthButtons[i]
			if monthButton.visible
				if paint.onPaintCalendarMonthButton != nil
					paint.onPaintCalendarMonthButton.call(monthButton, paint)
				else
					drawMonthButton(monthButton, paint)
				end
			end
		end
		monthFCButtonmSize = calendar.monthDiv.monthButtons_am.length
		for i in 0..monthFCButtonmSize - 1
			monthButton = calendar.monthDiv.monthButtons_am[i]
			if monthButton.visible
				if paint.onPaintCalendarMonthButton != nil
					paint.onPaintCalendarMonthButton.call(monthButton, paint)
				else
					drawMonthButton(monthButton, paint)
				end
			end
		end
	elsif calendar.mode == "year"
		yearButtonsSize = calendar.yearDiv.yearButtons.length
		for i in 0..yearButtonsSize - 1
			yearButton = calendar.yearDiv.yearButtons[i]
			if yearButton.visible
				if paint.onPaintCalendarYearButton != nil
					paint.onPaintCalendarYearButton.call(yearButton, paint)
				else
					drawYearButton(yearButton, paint)
				end
			end
		end
		yearFCButtonmSize = calendar.yearDiv.yearButtons_am.length
		for i in 0..yearFCButtonmSize - 1
			yearButton = calendar.yearDiv.yearButtons_am[i]
			if yearButton.visible
				if paint.onPaintCalendarYearButton != nil
					paint.onPaintCalendarYearButton.call(yearButton, paint)
				else
					drawYearButton(yearButton, paint)
				end
			end
		end
	end
	if paint.onPaintHeadDiv != nil
		paint.onPaintHeadDiv.call(calendar.headDiv, paint)
	else
		drawHeadDiv(calendar.headDiv, paint)
	end
	if calendar.borderColor != "none"
		paint.drawRect(calendar.borderColor, 1, 0, 0, 0, calendar.size.cx, calendar.size.cy)
	end
end

#点击日的按钮
#dayButton:日期按钮
#mp:坐标
def clickDayButton(dayButton, mp)
	calendar = dayButton.calendar
	lastDay = calendar.selectedDay
	calendar.selectedDay = dayButton.day
	selectDay(calendar.dayDiv, calendar.selectedDay, lastDay)
	updateCalendar(calendar)
	if calendar.paint != nil
	    invalidateView(calendar)
	end
end

#点击月的按钮
#monthButton:月按钮
#mp:坐标
def clickMonthButton(monthButton, mp)
	calendar = monthButton.calendar
	month = getYear(calendar.years, monthButton.year).months[monthButton.month]
	calendar.mode = "day"
	lastDay = calendar.selectedDay
	calendar.selectedDay = month.days[1]
	selectDay(calendar.dayDiv, calendar.selectedDay, lastDay)
	updateCalendar(calendar)
	if calendar.paint != nil
	    invalidateView(calendar)
	end
end

#点击年的按钮
#mp:坐标
#yearButton:年按钮
def clickYearButton(yearButton, mp)
	calendar = yearButton.calendar
	calendar.mode = "month"
	selectYear(calendar.monthDiv, yearButton.year)
	updateCalendar(calendar)
	if calendar.paint != nil
	    invalidateView(calendar)
	end
end

#点击左侧的按钮
#headDiv:头部层
#mp:坐标
def clickLastButton(headDiv, mp)
	calendar = headDiv.calendar
	if calendar.mode == "day"
		lastMonth = getLastMonth(calendar, calendar.selectedDay.year, calendar.selectedDay.month)
		lastDay = calendar.selectedDay
		calendar.selectedDay = lastMonth.days[1]
		selectDay(calendar.dayDiv, calendar.selectedDay, lastDay)
		updateCalendar(calendar)
		if calendar.paint != nil
			invalidateView(calendar)
		end
	elsif calendar.mode == "month"
		year = calendar.monthDiv.year
		year -= 1
		selectYear(calendar.monthDiv, year)
		updateCalendar(calendar)
		if calendar.paint != nil
			invalidateView(calendar)
		end
	elsif calendar.mode == "year"
		year = calendar.yearDiv.startYear
		year -= 12
		selectStartYear(calendar.yearDiv, year)
		updateCalendar(calendar)
		if calendar.paint != nil
		    invalidateView(calendar)
		end
	end
end

#点击右侧的按钮
#headDiv:头部层
#mp:坐标
def clickNextButton(headDiv, mp)
	calendar = headDiv.calendar
	if calendar.mode == "day"
		nextMonth = getNextMonth(calendar, calendar.selectedDay.year, calendar.selectedDay.month)
		lastDay = calendar.selectedDay
		calendar.selectedDay = nextMonth.days[1]
		selectDay(calendar.dayDiv, calendar.selectedDay, lastDay)
		updateCalendar(calendar)
		if calendar.paint != nil
			invalidateView(calendar)
		end
	elsif calendar.mode == "month"
		year = calendar.monthDiv.year
		year += 1
		selectYear(calendar.monthDiv, year)
		updateCalendar(calendar)
		if calendar.paint != nil
			invalidateView(calendar)
		end
	elsif calendar.mode == "year"
		year = calendar.yearDiv.startYear
		year += 12
		selectStartYear(calendar.yearDiv, year)
		updateCalendar(calendar)
		if calendar.paint != nil
		    invalidateView(calendar)
		end
	end
end

#改变模式的按钮
#headDiv:头部层
#mp:坐标
def clickModeButton(headDiv, mp)
	calendar = headDiv.calendar
	if calendar.mode == "day"
		calendar.mode = "month"
		calendar.monthDiv.month = calendar.selectedDay.month
		calendar.monthDiv.year = calendar.selectedDay.year
		updateCalendar(calendar)
		if calendar.paint != nil
			invalidateView(calendar)
		end
	elsif calendar.mode == "month"
		calendar.mode = "year"
		selectStartYear(calendar.yearDiv, calendar.monthDiv.year)
		updateCalendar(calendar)
		if calendar.paint != nil
		    invalidateView(calendar)
		end
	end
end

#点击日历
#calendar:日历
#mp:坐标
def clickCalendar(calendar, mp)
	headBounds = calendar.headDiv.bounds
	if mp.x >= headBounds.left && mp.x <= headBounds.right && mp.y >= headBounds.top && mp.y <= headBounds.bottom
		tR = 10
		if mp.x < headBounds.left + tR * 3
			clickLastButton(calendar.headDiv, mp)
			return
		elsif mp.x > headBounds.right - tR * 3
			clickNextButton(calendar.headDiv, mp)
			return
		else
			clickModeButton(calendar.headDiv, mp)
			return
		end
	end
	if calendar.mode == "day"
		dayButtonsSize = calendar.dayDiv.dayButtons.length
		for i in 0..dayButtonsSize - 1
			dayButton = calendar.dayDiv.dayButtons[i]
			if dayButton.visible
				bounds = dayButton.bounds
				if mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom
					clickDayButton(dayButton, mp)
					return
				end
			end
		end
	elsif calendar.mode == "month"
		monthButtonsSize = calendar.monthDiv.monthButtons.length
		for i in 0..monthButtonsSize - 1
			monthButton = calendar.monthDiv.monthButtons[i]
			if monthButton.visible
				bounds = monthButton.bounds
				if mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom
					clickMonthButton(monthButton, mp)
					return
				end
			end
		end
	else calendar.mode == "year"
		yearButtonsSize = calendar.yearDiv.yearButtons.length
		for i in 0..yearButtonsSize - 1
			yearButton = calendar.yearDiv.yearButtons[i]
			if yearButton.visible
				bounds = yearButton.bounds
				if mp.x >= bounds.left && mp.x <= bounds.right && mp.y >= bounds.top && mp.y <= bounds.bottom
					clickYearButton(yearButton, mp)
					return
				end
			end
		end
	end
end

#自动适应位置和大小
#menu:菜单
def adjustMenu(menu)
	resetLayoutDiv(menu)
	if menu.autoSize
		contentHeight = getDivContentHeight(menu)
		maximumHeight = menu.maximumSize.cy
		menu.size.cy = [contentHeight, maximumHeight].min
	end
	mPoint = menu.location
	mSize = menu.size
	paint = menu.paint
	nSize = FCSize.new(paint.size.cx / paint.scaleFactorX, paint.size.cy / paint.scaleFactorY)
	if mPoint.x < 0
		mPoint.x = 0
	end
	if mPoint.y < 0
		mPoint.y = 0
	end
	if mPoint.x + mSize.cx > nSize.cx
		mPoint.x = nSize.cx - mSize.cx
	end
	if mPoint.y + mSize.cy > nSize.cy
		mPoint.y = nSize.cy - mSize.cy
	end
	menu.location = mPoint
	menu.scrollV = 0
end

#添加菜单项
#item:菜单项
#menu:菜单
def addMenuItem(item, menu)
	addViewToParent(item, menu)
	item.parentMenu = menu
	menu.items.push(item)
end

#添加菜单项
#item:菜单项
#parentItem:父菜单项
def addMenuItemToParent(item, parentItem)
	item.parentItem = parentItem
	if parentItem.dropDownMenu == nil
		parentItem.dropDownMenu = FCMenu.new()
		addView(parentItem.dropDownMenu, parentItem.paint)
	end
	item.parentMenu = parentItem.dropDownMenu
	addViewToParent(item, parentItem.dropDownMenu)
	parentItem.items.append(item)
	parentItem.dropDownMenu.items.append(item)
end

#控制菜单的显示隐藏
#paint:绘图对象
def checkShowMenu(paint)
	paintAll = false
	clickItem = false
	for i in 0..paint.views.length - 1
		view = paint.views[i]
		if view.viewType == "menu"
			if view.visible
				if view == paint.touchDownView
					clickItem = true
				end
				for j in 0..view.items.length - 1
					item = view.items[j]
					if item == paint.touchDownView
						clickItem = true
						break
					end
				end
			end
		end
	end
	if clickItem == false
		for i in 0..paint.views.length - 1
			view = paint.views[i]
			if view.viewType == "menu"
				view.visible = false
				paintAll = true
			end
		end
	end
	if paintAll
		invalidate(paint)
	end
end

#关闭网格视图
#items:菜单集合
def closeMenus(items)
	itemSize = items.length
	close = false
	for i in 0..itemSize - 1
		item = items[i]
		subItems = item.items
		if closeMenus(subItems)
			close = true
		end
		dropDownMenu = item.dropDownMenu
		if dropDownMenu != nil && dropDownMenu.visible
			dropDownMenu.visible = false
			close = true
		end
	end
	return close
end

#鼠标移动到菜单项
#item 菜单项
def touchMoveMenuItem(item)
	parentItem = item.parentItem
	items = []
	if parentItem != nil
		if parentItem.dropDownMenu != nil
			items = parentItem.dropDownMenu.items
		end
	else
		if item.parentMenu != nil
			items = item.parentMenu.items
		end
	end
	closeMenus(items)
	if item.items.length > 0
		dropDownMenu = item.dropDownMenu
		#获取位置和大小
		if dropDownMenu != nil && dropDownMenu.visible == false
			layoutStyle = dropDownMenu.layoutStyle
			location = FCPoint.new(clientX(item) + item.size.cx, clientY(item))
			if layoutStyle == "lefttoright" || layoutStyle == "righttoleft"
				location.x = clientX(item)
				location.y = clientY(item) + item.size.cy
			end
			#设置弹出位置
			dropDownMenu.location = location
			dropDownMenu.visible = true
			adjustMenu(dropDownMenu)
			invalidate(item.paint)
			return
		end
	invalidate(item.paint)
	end
end

#重绘按钮
#item:菜单项
#paint:绘图对象
#clipRect:裁剪区域
def drawMenuItem(item, paint, clipRect)
	if item == paint.touchDownView
		if item.pushedColor != nil
			paint.fillRect(item.pushedColor, 0, 0, item.size.cx, item.size.cy)
		else
			if item.backColor != nil
				paint.fillRect(item.backColor, 0, 0, item.size.cx, item.size.cy)
			end
		end
	elsif item == paint.touchMoveView
		if item.hoveredColor != nil
			paint.fillRect(item.hoveredColor, 0, 0, item.size.cx, item.size.cy)
		else
			if item.backColor != nil
				paint.fillRect(item.backColor, 0, 0, item.size.cx, item.size.cy)
			end
		end
	elsif item.backColor != nil
		paint.fillRect(item.backColor, 0, 0, item.size.cx, item.size.cy)
	end
	if item.textColor != nil && item.text.length > 0
		tSize = paint.textSize(item.text, item.font)
		paint.drawText(item.text, item.textColor, item.font, (item.size.cx - tSize.cx) / 2, (item.size.cy - tSize.cy) / 2)
	end
	if item.borderColor != nil
		paint.drawRect(item.borderColor, item.borderWidth, 0, 0, 0, item.size.cx, item.size.cy)
	end
	if item.items.length > 0
		tR = 5
		drawPoints = []
		drawPoints.push(FCPoint.new(item.size.cx - 2, item.size.cy / 2))
		drawPoints.push(FCPoint.new(item.size.cx - 2 - tR * 2, item.size.cy / 2 - tR))
		drawPoints.push(FCPoint.new(item.size.cx - 2 - tR * 2, item.size.cy / 2 + tR))
		paint.fillPolygon(item.textColor, drawPoints)
	end
end

#点击菜单项
#item:菜单项
def clickMenuItem(item)
	paintAll = false
	if item.parentMenu != nil
		if item.parentMenu.comboBox != nil
			index = -1
			for i in 0..item.parentMenu.items.length - 1
				if item.parentMenu.items[i] == item
					index = i
					break
				end
			end
			item.parentMenu.comboBox.selectedIndex = index
			item.parentMenu.comboBox.text = item.parentMenu.items[index].text
			paintAll = true
		end
	end
	if item.items.length == 0
		for i in 0..item.paint.views.length - 1
			subView = item.paint.views[i]
			if subView.viewType == "menu"
				if subView.visible
					subView.visible = false
					paintAll = true
				end
			end
		end
	end
	if paintAll
		invalidate(item.paint)
	end
end

#重绘按钮
#comboBox:下拉列表
#paint:绘图对象
#clipRect:裁剪区域
def drawComboBox(comboBox, paint, clipRect)
	if comboBox.backColor != nil
		paint.fillRect(comboBox.backColor, 0, 0, comboBox.size.cx, comboBox.size.cy)
	end
	if comboBox.textColor != nil && comboBox.text.length > 0
		tSize = paint.textSize(comboBox.text, comboBox.font)
		paint.drawText(comboBox.text, comboBox.textColor, comboBox.font, 5, (comboBox.size.cy - tSize.cy) / 2)
	end
	if comboBox.borderColor != nil
		paint.drawRect(comboBox.borderColor, comboBox.borderWidth, 0, 0, 0, comboBox.size.cx, comboBox.size.cy)
	end
	tR = 5
	drawPoints = []
	drawPoints.push(FCPoint.new(comboBox.size.cx - 5 - tR * 2, comboBox.size.cy / 2 - tR))
	drawPoints.push(FCPoint.new(comboBox.size.cx - 5, comboBox.size.cy / 2 - tR))
	drawPoints.push(FCPoint.new(comboBox.size.cx - 5 - tR, comboBox.size.cy / 2 + tR))
	paint.fillPolygon(comboBox.textColor, drawPoints)
end

#点击下拉菜单
#comboBox:下拉菜单
def clickComboBox(comboBox)
	showX = clientX(comboBox)
	showY = clientY(comboBox) + comboBox.size.cy
	comboBox.dropDownMenu.location = FCPoint.new(showX, showY)
	comboBox.dropDownMenu.visible = true
	adjustMenu(comboBox.dropDownMenu)
	invalidate(comboBox.paint)
end

#设置属性
#view:视图
#node:xml节点
def setAttributeDefault(view, child)
	if view.paint != nil
		if view.paint.defaultUIStyle == "dark"
			view.backColor = "rgb(0,0,0)"
			view.borderColor = "rgb(100,100,100)"
			view.textColor = "rgb(255,255,255)"
			view.scrollBarColor = "rgb(100,100,100)"
		elsif view.paint.defaultUIStyle == "light"
			view.backColor = "rgb(255,255,255)"
			view.borderColor = "rgb(150,150,150)"
			view.textColor = "rgb(0,0,0)"
			view.scrollBarColor = "rgb(200,200,200)"
		end
		child.attributes.each do |key,value|
			name = key.downcase
			if name == "location"
				xStr = value.split(",")[0]
				yStr = value.split(",")[1]
				if xStr.include?("%")
					view.exAttributes["leftstr"] = xStr
				else
					view.location.x = xStr.to_i
				end
				if yStr.include?("%")
					view.exAttributes["topstr"] = yStr
				else
					view.location.y = yStr.to_i
				end
			elsif name == "size"
				xStr = value.split(",")[0]
				yStr = value.split(",")[1]
				if xStr.include?("%")
					view.exAttributes["widthstr"] = xStr
				else
					view.size.cx = xStr.to_i
				end
				if yStr.include?("%")
					view.exAttributes["heightstr"] = yStr
				else
					view.size.cy = yStr.to_i
				end
			elsif name == "text"
				view.text = value
			elsif name == "backcolor"
				lowerStr = value.downcase
				if lowerStr.include?("rgb")
					view.backColor = value
				else
					view.backColor = "none"
				end
			elsif name == "bordercolor"
				lowerStr = value.downcase
				if lowerStr.include?("rgb")
					view.borderColor = value
				else
					view.borderColor = "none"
				end
			elsif name == "textcolor"
				lowerStr = value.downcase
				if lowerStr.include?("rgb")
					view.textColor = value
				else
					view.textColor = "none"
				end
			elsif name == "layoutstyle"
				view.layoutStyle = value.downcase
			elsif name == "align"
				view.align = value.downcase
			elsif name == "cursor"
				view.cursor = value.downcase
			elsif name == "vertical-align"
				view.verticalAlign = value.downcase
			elsif name == "dock"
				view.dock = value.downcase
			elsif name == "font"
				view.font = value
			elsif name == "headerheight"
				view.headerHeight = value.to_f
			elsif name == "cornerradius"
				view.cornerRadius = value.to_f
			elsif name == "borderwidth"
				view.borderWidth = value.to_f
			elsif name == "splitmode"
				view.splitMode = value.downcase
			elsif name == "autowrap"
				view.autoWrap = (value.downcase == "true")
			elsif name == "tabindex"
				view.tabIndex = value.to_i
			elsif name == "tabstop"
				view.tabStop = (value.downcase == "true")
			elsif name == "name"
				view.viewName = value
			elsif name == "enabled"
				view.enabled = (value.downcase == "true")
			elsif name == "showvscrollbar"
				view.showVScrollBar = (value.downcase == "true")
			elsif name == "showhscrollbar"
				view.showHScrollBar = (value.downcase == "true")
			elsif name == "visible"
				view.visible = (value.downcase == "true")
			elsif name == "displayoffset"
				view.displayOffset = (value.downcase == "true")
			elsif name == "checked"
				view.checked = (value.downcase == "true")
			elsif name == "buttonsize"
				view.buttonSize = FCSize.new(value.split(",")[0].to_i, value.split(",")[1].to_i)
			elsif name == "topmost"
				view.topMost = (value.downcase == "true")
			elsif name == "selectedindex"
				view.selectedIndex = value.to_i
			elsif name == "src"
				view.src = value
			elsif name == "backimage"
				view.backImage = value
			elsif name == "groupname"
				view.groupName = value
			elsif name == "allowdragscroll"
				view.allowDragScroll = (value.downcase == "true")
			elsif name == "allowpreviewsevent"
				view.allowPreviewsEvent = (value.downcase == "true")
			elsif name == "allowdrag"
				view.allowDrag = (value.downcase == "true")
			elsif name == "allowresize"
				view.allowResize = (value.downcase == "true")
			elsif name == "indent"
				view.indent = value.to_f
			elsif name == "showcheckbox"
				view.showCheckBox = (value.downcase == "true")
			elsif name == "padding"
				view.padding = FCPadding.new(value.split(",")[0].to_i, value.split(",")[1].to_i, value.split(",")[2].to_i, value.split(",")[3].to_i)
			elsif name == "margin"
				view.margin = FCPadding.new(value.split(",")[0].to_i, value.split(",")[1].to_i, value.split(",")[2].to_i, value.split(",")[3].to_i)
			elsif name == "hoveredcolor"
				lowerStr = value.downcase
				if lowerStr.include?("rgb")
					view.hoveredColor = value
				else
					view.hoveredColor = "none"
				end
			elsif name == "pushedcolor"
				lowerStr = value.downcase
				if lowerStr.include?("rgb")
					view.pushedColor = value
				else
					view.pushedColor = "none"
				end
			elsif name == "layout"
				view.layout = value
			elsif name == "width"
				if value.include?("%")
					view.exAttributes["widthstr"] = value
				else
					view.size.cx = value.to_i
				end
			elsif name == "height"
				if value.include?("%")
					view.exAttributes["heightstr"] = value
				else
					view.size.cy = value.to_i
				end
			elsif name == "top"
				if value.include?("%")
					view.exAttributes["topstr"] = value
				else
					view.location.y = value.to_i
				end
			elsif name == "left"
				if value.include?("%")
					view.exAttributes["leftstr"] = value
				else
					view.location.x = value.to_i
				end
			else
				view.exAttributes[name] = value
			end
		end
	end 
end

#读取Xml中的树节点
#tree 树
#parentNode 父节点
#xmlNode Xml节点
def readTreeXmlNodeDefault(tree, parentNode, xmlNode)
	treeNode = FCTreeNode.new()
	treeNode.value = xmlNode.attributes["text"]
	appendTreeNode(tree, treeNode, parentNode)
	xmlNode.elements.each() do |child|
		nodeName = child.name.downcase
		if nodeName == "node"
			readTreeXmlNodeDefault(tree, treeNode, child)
		end
	end
end

#读取Xml
#paint 绘图对象
#node节点
#parent 父视图
def readXmlNodeDefault(paint, node, parent)
	node.elements.each() do |child|
		view = nil
		typeStr = ""
		nodeName = child.name.downcase
		if nodeName == "div" || nodeName == "view"
			if child.attributes.has_key?("type")
				typeStr = child.attributes["type"]
			end
			if typeStr == "splitlayout"
				view = FCSplitLayoutDiv.new()
			elsif typeStr == "layout"
				view = FCLayoutDiv.new()
			elsif typeStr == "tab"
				view = FCTabView.new()
			elsif typeStr == "tabpage"
				view = FCTabPage.new()
			elsif typeStr == "radio"
				view = FCRadioButton.new()
				view.backColor = "none"
			elsif typeStr == "checkbox"
				view = FCCheckBox.new()
				view.backColor = "none"
			elsif typeStr == "button"
				view = FCButton.new()
			elsif typeStr == "text" or typeStr == "range" or typeStr == "datetime"
				view = FCTextBox.new()
			elsif typeStr == "custom"
				cid = child.attributes["cid"]
				view = FCDiv.new()
				view.viewType = cid
			else
				view = FCDiv.new()
			end
		elsif nodeName == "table"
			view = FCGrid.new()
		elsif nodeName == "chart"
			view = FCChart.new()
		elsif nodeName == "tree"
			view = FCTree.new()
		elsif nodeName == "select"
			view = FCComboBox.new()
		elsif nodeName == "calendar"
			view = FCCalendar.new()
		elsif nodeName == "label"
			view = FCLabel.new()
		elsif nodeName == "input"
			if child.attributes.has_key?("type")
				typeStr = child.attributes["type"]
			end
			if typeStr == "radio"
				view = FCRadioButton.new()
				view.backColor = "none"
			elsif typeStr == "checkbox"
				view = FCCheckBox.new()
				view.backColor = "none"
			elsif typeStr == "button"
				view = FCButton.new()
			elsif typeStr == "text" or typeStr == "range" or typeStr == "datetime"
				view = FCTextBox.new()
			elsif typeStr == "custom"
				cid = child.attributes["cid"]
				view = FCView.new()
				view.viewType = cid
			else
				view = FCButton.new()
			end
		else
			view = FCView.new()
		end
		if view != nil
			view.paint = paint
			view.parent = parent
			setAttributeDefault(view, child)
			if typeStr == "tabpage"
				tabButton = FCView.new()
				tabButton.viewType = "tabbutton"
				if child.attributes.has_key?("headersize")
					atrHeaderSize = child.attributes["headersize"]
					tabButton.size = FCSize.new(atrHeaderSize.split(",")[0].to_i, atrHeaderSize.split(",")[1].to_i)
				else
					tabButton.size = FCSize.new(100, 20)
				end
				if view.paint.defaultUIStyle == "dark"
					tabButton.backColor = "rgb(0,0,0)"
					tabButton.borderColor = "rgb(100,100,100)"
					tabButton.textColor = "rgb(255,255,255)"
				elsif view.paint.defaultUIStyle == "light"
					tabButton.backColor = "rgb(255,255,255)"
					tabButton.borderColor = "rgb(150,150,150)"
					tabButton.textColor = "rgb(0,0,0)"
				end
				tabButton.text = view.text
				tabButton.paint = paint
				addTabPage(view.parent, view, tabButton)
			else
				if parent != nil
					parent.views.push(view)
				else
					paint.views.push(view)
				end
			end
			if typeStr == "splitlayout"
				if child.attributes.has_key?("datumsize")
					atrDatum = child.attributes["datumsize"]
					view.size = FCSize.new(atrDatum.split(",")[0].to_i, atrDatum.split(",")[1].to_i)
				end
				splitter = FCView.new()
				splitter.paint = paint
				splitter.parent = view
				if view.paint.defaultUIStyle == "dark"
					splitter.backColor = "rgb(100,100,100)"
				elsif view.paint.defaultUIStyle == "light"
					splitter.backColor = "rgb(150,150,150)"
				end
				if child.attributes.has_key?("candragsplitter")
					if child.attributes["candragsplitter"] == "true"
						splitter.allowDrag = true
					end
				end
				view.splitter = splitter
				splitterposition = child.attributes["splitterposition"]
				splitStr = splitterposition.split(",")
				if splitStr.length >= 4
					splitRect = FCRect.new(splitStr[0].to_f, splitStr[1].to_f, splitStr[2].to_f, splitStr[3].to_f)
					splitter.location = FCPoint.new(splitRect.left, splitRect.top)
					splitter.size = FCSize.new(splitRect.right - splitRect.left, splitRect.bottom - splitRect.top)
				else
					sSize = splitStr[1].to_f
					sPosition = splitStr[0].to_f
					if view.layoutStyle == "lefttoright" || view.layoutStyle == "righttoleft"
						splitter.location = FCPoint.new(sPosition, 0)
						splitter.size = FCSize.new(sSize, view.size.cy)
					else
						splitter.location = FCPoint.new(0, sPosition)
						splitter.size = FCSize.new(view.size.cx, sSize)
					end
				end
				readXmlNodeDefault(paint, child, view)
				subViews = view.views
				view.firstView = subViews[0]
				view.secondView = subViews[1]
				view.views.push(splitter)
				view.oldSize = FCSize.new(view.size.cx, view.size.cy)
				resetSplitLayoutDiv(view)
			elsif typeStr == "tab"
				readXmlNodeDefault(paint, child, view)
				tabPages = view.tabPages
				if tabPages.length > 0
					if child.attributes.has_key?("selectedindex")
						strSelectedIndex = child.attributes["selectedindex"]
						selectedIndex = strSelectedIndex.to_i
						if selectedIndex >= 0 && selectedIndex < tabPages.length
							tabPages[selectedIndex].visible = true
						else
							tabPages[tabPages.length - 1].visible = true
						end
					else
						tabPages[tabPages.length - 1].visible = true
					end
				end
			elsif nodeName == "table"
				child.elements.each() do |tChild|
					if tChild.name == "tr"
						gridRow = nil
						tChild.elements.each() do |sunNode|
							sunNodeName = sunNode.name.downcase
							if sunNodeName == "th"
								gridColumn = FCGridColumn.new()
								if view.paint.defaultUIStyle == "light"
									gridColumn.backColor = "rgb(230,230,230)"
									gridColumn.borderColor = "rgb(150,150,150)"
									gridColumn.textColor = "rgb(0,0,0)"
								elsif view.paint.defaultUIStyle == "dark"
									gridColumn.backColor = "rgb(50,50,50)"
									gridColumn.borderColor = "rgb(100,100,100)"
									gridColumn.textColor = "rgb(255,255,255)"
								end
								gridColumn.width = 100
								if sunNode.attributes.has_key?("text")
									gridColumn.text = sunNode.attributes["text"]
								end
								if sunNode.attributes.has_key?("width")
									strWidth = sunNode.attributes["width"]
									if strWidth.include?("%")
										gridColumn.widthStr = strWidth
									else
										gridColumn.width = strWidth.to_f
									end
								end
								if sunNode.attributes.has_key?("backcolor")
									gridColumn.backColor = sunNode.attributes["backcolor"]
								end
								if sunNode.attributes.has_key?("textcolor")
									gridColumn.textColor = sunNode.attributes["textcolor"]
								end
								if sunNode.attributes.has_key?("bordercolor")
									gridColumn.borderColor = sunNode.attributes["bordercolor"]
								end
								if sunNode.attributes.has_key?("font")
									gridColumn.font = sunNode.attributes["font"]
								end
								view.columns.push(gridColumn)
							elsif sunNodeName == "td"
								if gridRow == nil
									gridRow = FCGridRow.new()
									view.rows.push(gridRow)
								end
								gridCell = FCGridCell.new()
                                gridCell.value = sunNode.text
                                gridRow.cells.push(gridCell)
							end
						end
					end
				end
			elsif nodeName == "tree"
				treeColumn = FCTreeColumn.new()
				view.columns.push(treeColumn)
				columnWidth = 0
				child.elements.each() do |tChild|
					if tChild.name == "nodes"
						tChild.elements.each() do |sunNode|
							sunNodeName = sunNode.name.downcase
							if sunNodeName == "node"
								readTreeXmlNodeDefault(view, nil, sunNode)
							end
						end
					elsif if tChild.name == "tr"
						tChild.elements.each() do |sunNode|
							sunNodeName = sunNode.name.downcase
							if sunNodeName == "th"
								if sunNode.attributes.has_key?("width")
									strWidth = sunNode.attributes["width"]
									if strWidth.include?("%")
										treeColumn.widthStr = strWidth
									else
										columnWidth += strWidth.to_f
									end
								end
							end
						end
					end
					end
				end
				if columnWidth > 0
					treeColumn.width = columnWidth
				end
			elsif view.viewType == "textbox"
				view.exView = true
				pType = Fiddle::Pointer[view.viewType]
				pName = Fiddle::Pointer[view.viewName]
				$createView.call(paint.gID.to_i, pType, pName)
				if view.paint.defaultUIStyle == "dark"
					$setAttribute2.call(paint.gID.to_i, pName, Fiddle::Pointer["backcolor"], Fiddle::Pointer["rgb(0,0,0)"])
					$setAttribute2.call(paint.gID.to_i, pName, Fiddle::Pointer["bordercolor"], Fiddle::Pointer["rgb(100,100,100)"])
					$setAttribute2.call(paint.gID.to_i, pName, Fiddle::Pointer["textcolor"], Fiddle::Pointer["rgb(255,255,255)"])
				elsif view.paint.defaultUIStyle == "light"
					$setAttribute2.call(paint.gID.to_i, pName, Fiddle::Pointer["backcolor"], Fiddle::Pointer["rgb(255,255,255)"])
					$setAttribute2.call(paint.gID.to_i, pName, Fiddle::Pointer["bordercolor"], Fiddle::Pointer["rgb(150,150,150)"])
					$setAttribute2.call(paint.gID.to_i, pName, Fiddle::Pointer["textcolor"], Fiddle::Pointer["rgb(150,150,150)"])
				end
				child.attributes.each do |key,value|
					name = key.downcase
					aName = Fiddle::Pointer[name]
					aValue = Fiddle::Pointer[value]
					$setAttribute2.call(paint.gID.to_i, pName, aName, aValue)
				end
			elsif nodeName == "calendar"
				initCalendar(view)
				view.selectedDay = getYear(view.years, 2022).months[10].days[1]
			elsif nodeName == "select"
				view.dropDownMenu = FCMenu.new()
				view.dropDownMenu.comboBox = view
				addView(view.dropDownMenu, paint)
				view.dropDownMenu.size.cx = view.size.cx
				child.elements.each() do |tChild|
					if tChild.name == "option"
						menuItem = FCMenuItem.new()
						addMenuItem(menuItem, view.dropDownMenu)
						setAttributeDefault(menuItem, tChild)
					end
				end
				if view.dropDownMenu.items.length > 0
					if child.attributes.has_key?("selectedindex")
						strSelectedIndex = child.attributes["selectedindex"]
						selectedIndex = strSelectedIndex.to_i
						if selectedIndex >= 0 && selectedIndex < view.dropDownMenu.items.length
							view.selectedIndex = selectedIndex
							view.text = view.dropDownMenu.items[selectedIndex].text
						else
							view.selectedIndex = 0
							view.text = view.dropDownMenu.items[0].text
						end
					else
						view.selectedIndex = 0
						view.text = view.dropDownMenu.items[0].text
					end
				end
			else
				if view.viewType != "chart"
					readXmlNodeDefault(paint, child, view)
				end
			end
		end
	end
end

#加载FaceCat
#paint:绘图对象
#xml:Xml内容
def renderFaceCat(paint, xml)
	xmldoc = Document.new(xml)
	root = xmldoc.root
	root.elements.each() do |element|
		if element.name == "body"
			readXmlNodeDefault(paint, element, nil)
		end
	end
	if paint.onUpdateView != nil
		paint.onUpdateView.call(paint.views)
	else
		updateViewDefault(paint.views)
	end
	invalidate(paint)
end

#绘制视图
#view:视图
#paint:绘图对象
#clipRect:区域
def onPaintDefault(view, paint, clipRect)
	if view.viewType == "radiobutton"
		drawRadioButton(view, paint, clipRect)
	elsif view.viewType == "checkbox"
		drawCheckBox(view, paint, clipRect)
	elsif view.viewType == "chart"
		drawChart(view, paint, clipRect)
	elsif view.viewType == "grid"
		drawDiv(view, paint, clipRect)
		drawGrid(view, paint, clipRect)
	elsif view.viewType == "tree"
		drawDiv(view, paint, clipRect)
		drawTree(view, paint, clipRect)
	elsif view.viewType == "label"
		if view.textColor != "none"
			tSize = paint.textSize(view.text, view.font)
			paint.drawText(view.text, view.textColor, view.font, 0, (view.size.cy - tSize.cy) / 2)
		end
	elsif view.exView
		pName = Fiddle::Pointer[view.viewName]
		$paintView.call(paint.gID.to_i, pName, 0, 0, view.size.cx.to_i, view.size.cy.to_i)
	elsif view.viewType == "div" || view.viewType =="tabpage" || view.viewType =="tabview" || view.viewType =="layout"
		drawDiv(view, paint, clipRect)
	elsif view.viewType == "calendar"
		drawCalendar(view, paint)
	elsif view.viewType == "menuitem"
		drawMenuItem(view, paint, clipRect)
	elsif view.viewType == "combobox"
		drawComboBox(view, paint, clipRect)
	else
		drawButton(view, paint, clipRect)
	end
end

#绘制视图边线
#view:视图
#paint:绘图对象
#clipRect:区域
def onPaintBorderDefault(view, paint, clipRect)
	if view.viewType == "grid"
		drawGridScrollBar(view, paint, clipRect)
		drawDivBorder(view, paint, clipRect)
	elsif view.viewType == "tree"
		drawTreeScrollBar(view, paint, clipRect)
		drawDivBorder(view, paint, clipRect)
	elsif view.viewType == "div" || view.viewType =="tabpage" || view.viewType =="tabview" || view.viewType =="layout" || view.viewType == "menu"
		drawDivBorder(view, paint, clipRect)
		drawDivScrollBar(view, paint, clipRect)
	elsif view.viewType == "textbox"
		drawDivBorder(view, paint, clipRect)
	end
end

#视图的鼠标移动方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseMoveDefault(view, mp, buttons, clicks, delta)
	firstTouch = false
	secondTouch = false
	firstPoint = mp
	secondPoint = mp
	if buttons == 1
		firstTouch = true
	elsif buttons == 2
		secondTouch = true
	end
	if view.viewType == "grid"
		touchMoveGrid(view, firstTouch, firstPoint, secondTouch, secondPoint)
		invalidateView(view)
	elsif view.viewType == "tree"
		touchMoveTree(view, firstTouch, firstPoint, secondTouch, secondPoint)
		invalidateView(view)
	elsif view.viewType == "chart"
		touchMoveChart(view, firstTouch, firstPoint, secondTouch, secondPoint)
		invalidateView(view)
	elsif view.viewType == "div" || view.viewType =="layout" || view.viewType == "menu"
		touchMoveDiv(view, firstTouch, firstPoint, secondTouch, secondPoint)
		invalidateView(view)
	elsif view.viewType == "button"
		invalidateView(view)
	elsif view.viewType == "menuitem"
		touchMoveMenuItem(view)
	else
		invalidateView(view)
	end
end
		
#视图的鼠标按下方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseDownDefault(view, mp, buttons, clicks, delta)
	firstTouch = false
	secondTouch = false
	firstPoint = mp
	secondPoint = mp
	if buttons == 1
		firstTouch = true
	elsif buttons == 2
		secondTouch = true
	end
	if view.viewType == "grid"
		touchDownGrid(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
		invalidateView(view)
	elsif view.viewType == "tree"
		touchDownTree(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
		invalidateView(view)
	elsif view.viewType == "chart"
		touchDownChart(view, firstTouch, firstPoint, secondTouch, secondPoint)
		invalidateView(view)
	elsif view.viewType == "div" || view.viewType =="layout" || view.viewType == "menu"
		touchDownDiv(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
		invalidateView(view)
	elsif view.viewType == "button"
		invalidateView(view)
	elsif view.viewType == "calendar"
		clickCalendar(view, firstPoint)
	end
end

#视图的鼠标抬起方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseUpDefault(view, mp, buttons, clicks, delta)
	firstTouch = false
	secondTouch = false
	firstPoint = mp
	secondPoint = mp
	if buttons == 1
		firstTouch = true
	elsif buttons == 2
		secondTouch = true
	end
	if view.viewType == "grid"
		touchUpGrid(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	elsif view.viewType == "tree"
		touchUpTree(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	elsif view.viewType == "div" || view.viewType =="layout" || view.viewType == "menu"
		touchUpDiv(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	elsif view.viewType == "chart"
		view.firstTouchIndexCache = -1
		view.secondTouchIndexCache = -1
	end
	invalidateView(view)
end

#视图的鼠标点击方法
#view 视图
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks:点击次数
def onClickDefault(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	if view.viewType == "radiobutton"
		clickRadioButton(view, firstPoint)
		if view.parent != nil
			invalidateView(view.parent)
		else
			invalidateView(view)
		end
	elsif view.viewType == "checkbox"
		clickCheckBox(view, firstPoint)
		invalidateView(view)
	elsif view.viewType == "tabbutton"
		tabView = view.parent
		for i in 0..tabView.tabPages.length - 1
			if tabView.tabPages[i].headerButton == view
				selectTabPage(tabView, tabView.tabPages[i])
			end
		end
		invalidateView(tabView)
	elsif view.viewType == "menuitem"
		clickMenuItem(view)
	elsif view.viewType == "combobox"
		clickComboBox(view)
	end
end

#视图的鼠标滚动方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseWheelDefault(view, mp, buttons, clicks, delta)
	if view.viewType == "grid"
		touchWheelGrid(view, delta)
		invalidateView(view)
	elsif view.viewType == "tree"
		touchWheelTree(view, delta)
		invalidateView(view)
	elsif view.viewType == "div" || view.viewType =="layout" || view.viewType =="menu"
		touchWheelDiv(view, delta)
		invalidateView(view)
	elsif view.viewType == "chart"
		if delta > 0
			zoomOutChart(view)
		elsif delta < 0
			zoomInChart(view)
		end
		invalidateView(view)
	end
end

#视图的键盘按下方法
#view 视图
#value 按键值
def onKeyDownDefault(view, value)
	if view.viewType == "chart"
		if value == 38
			zoomOutChart(view)
		elsif value == 40
			zoomInChart(view)
		end
		invalidateView(view)
	end
end

#视图的键盘抬起方法
#view 视图
#value 按键值
def onKeyUpDefault(view, value)
end

#视图的键盘输入方法
#view 视图
#value 按键值
def onCharDefault(view, value)
end

#默认的消息循环处理
def WndProcDefault(paint, hWnd, message, wParam, lParam)
	if message == WM_LBUTTONDOWN
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		handleMouseDown(mp, 1, 1, 0, paint)
	elsif message == WM_RBUTTONDOWN
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		handleMouseDown(mp, 2, 1, 0, paint)
	elsif message == WM_LBUTTONDBLCLK
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		handleMouseDown(mp, 1, 2, 0, paint)
	elsif message == WM_RBUTTONDBLCLK
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		handleMouseDown(mp, 2, 2, 0, paint)
	elsif message == WM_LBUTTONUP
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		if paint.isDoubleClick
			handleMouseUp(mp, 1, 2, 0, paint)
		else
			handleMouseUp(mp, 1, 1, 0, paint)
		end
	elsif message == WM_RBUTTONUP
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		if paint.isDoubleClick
			handleMouseUp(mp, 2, 2, 0, paint)
		else
			handleMouseUp(mp, 2, 1, 0, paint)
		end
	elsif message == WM_MOUSEMOVE
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		if wParam == 1
			handleMouseMove(mp, 1, 1, 0, paint)
		elsif wParam == 2
			handleMouseMove(mp, 2, 1, 0, paint)
		else
			handleMouseMove(mp, 0, 0, 0, paint)
		end
	elsif message == WM_MOUSEWHEEL
		ccx = $getMouseX.call(paint.hWnd)
		ccy = $getMouseY.call(paint.hWnd)
		mp = FCPoint.new(ccx, ccy)
		mp.x /= paint.scaleFactorX
		mp.y /= paint.scaleFactorY
		if wParam < 0
			handleMouseWheel(mp, 0, 0, -1, paint)
		else
			handleMouseWheel(mp, 0, 0, 1, paint)
		end
	elsif message == WM_IME_COMPOSITION || message == WM_IME_CHAR || message == WM_IME_SETCONTEXT
		$setMessageState.call(paint.gID.to_i, 1)
	elsif message == WM_CHAR || message == WM_KEYDOWN || message == WM_SYSKEYDOWN || message == WM_KEYUP || message == WM_SYSKEYUP
		if paint.focusedView != nil
			if paint.focusedView.exView
				$setMessageState.call(paint.gID.to_i, 1)
				invalidateView(paint.focusedView)
			end
			if message == WM_KEYDOWN || message == WM_SYSKEYDOWN
				if paint.onKeyDown != nil
					paint.onKeyDown.call(paint.focusedView, wParam)
				else
					onKeyDownDefault(paint.focusedView, wParam)
				end
			elsif message == WM_KEYUP || message == WM_SYSKEYUP
				if paint.onKeyUp != nil
					paint.onKeyUp.call(paint.focusedView, wParam)
				else
					onKeyUpDefault(paint.focusedView, wParam)
				end
			elsif message == WM_CHAR
				if paint.onChar != nil
					paint.onChar.call(paint.focusedView, wParam)
				else
					onCharDefault(paint.focusedView, wParam)
				end
			end
		end
	elsif message == WM_PAINT
		wWidth = $getWindowWidth.call(hWnd)
		wHeight = $getWindowHeight.call(hWnd)
		if paint.size.cx != wWidth || paint.size.cy != wHeight
			paint.size = FCSize.new(wWidth, wHeight)
			if paint.onUpdateView != nil
				paint.onUpdateView.call(paint.views)
			else
				updateViewDefault(paint.views)
			end
		end
		invalidate(paint)
	elsif message = WM_SIZE
		wWidth = $getWindowWidth.call(hWnd)
		wHeight = $getWindowHeight.call(hWnd)
		if paint.size.cx != wWidth || paint.size.cy != wHeight
			paint.size = FCSize.new(wWidth, wHeight)
			if paint.onUpdateView != nil
				paint.onUpdateView.call(paint.views)
			else
				updateViewDefault(paint.views)
			end
		end
		invalidate(paint)
	end
end

#初始化环境
def initWindow()
	$showWindow.call()
end

#创建窗体
def createWindow(paint)
	$showWindowMax.call()
	paint.hWnd = $getHWnd.call()
	paint.gID = $createGdiPlus.call(paint.hWnd)
	paint.size = FCSize.new($getWindowWidth.call(paint.hWnd), $getWindowHeight.call(paint.hWnd))
end

#消息循环
def showWindow()
	$pumpMessage.call()
end